Exemplo n.º 1
0
long outOfMoneyOption(vector<Asset*>& assets, double startMoney){ //based on what

	Asset* calls;
	Asset* puts;
	Asset* underlyer;
	double tCRatio = 0.01; //records the transaction cost ratio
	if (assets.size() != 3){
		cerr << " Wrong number of objects to test outOfMoneyOption" << endl;
		exit (EXIT_FAILURE);
	}

	if (assets.at(0)->getIsEquity() == 1){ //first object is Equity
		underlyer = assets.at(0);
		if(assets.at(1)->getIsCall() == 1){ //second object is calls
			calls = assets.at(1);
			puts = assets.at(2);
		}
		else{
			calls = assets.at(2);
			puts = assets.at(1);
		}
	}
	else if (assets.at(0)->getIsOption() == 1){
		if(assets.at(0)->getIsCall() == 1){
			calls = assets.at(0);
			if(assets.at(1)->getIsEquity() == 1){
				underlyer = assets.at(1);
				puts = assets.at(2);
			}
			else{
				underlyer = assets.at(2);
				puts = assets.at(1);
			}

		}
		else{
			puts = assets.at(0);
			if(assets.at(1)->getIsEquity() == 1){
				underlyer = assets.at(1);
				calls = assets.at(2);
			}
			else{
				underlyer = assets.at(2);
				calls = assets.at(1);
			}
		}
	}

	//we have the required types of data: perform back-test.
	//Simple strat that just keeps cash adn trades 20% of portfolio in out of the money straddle.
	//Equity information is contained is separate object.

	struct stat fStatus; //where all the output will be in for further analysis
	string outputFile = assets.at(0)->getWriteTo()+ "/" + "outOfMoneyOption.csv";
	int thereOrNot = stat(outputFile.c_str(), &fStatus);
	ofstream dataOut(outputFile.c_str(), ios_base::out | ios_base::app); //append to file only will create file if not there
	if (thereOrNot == -1) //file not already created.
		dataOut << "Date," << "Capital," << "Cash," << "calls," << "puts" << endl;
	else{}//do nothing


	double currCash = startMoney;
	deque<double>results;
	results.push_back(startMoney);
	double nbrCalls = 0; //in practice, very hard to get a perfect straddle, so numbers will vary.
	double nbrPuts = 0;
	double callID = 0; //ID of currently held call contracts
	double putID = 0; //ID of currently held put contracts
	size_t equityIndex = 0;
	long currDate = underlyer->getDate(equityIndex);
	dataOut << currDate << "," << currCash
			<< "," << currCash << "," << nbrCalls << "," << nbrPuts << endl;

	size_t callsPos = 0;
	size_t putsPos = 0;
	double oufOfMoneyRatio = 0.2; // certainly need to data mine this value.

	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	//////////////////// find option closest to outOfMoneyRatio ////////////////////////
	while (calls->getDate(callsPos) == currDate){

		callsDailyVol += calls->getVolume(callsPos);
		callsDailyOoi += calls->getOoi(callsPos);
		++callsPos;
		if(callsPos == calls->getNbrRows()) break;
	}

	//get puts daily volume and open interest for all options on given day.
	while (puts->getDate(putsPos) == currDate){ //while I am on one date
		putsDailyVol += puts->getVolume(putsPos);
		putsDailyOoi += puts->getOoi(putsPos);
		++putsPos;
		if(putsPos == puts->getNbrRows()) break;
	}

	prevPcVolRatio = putsDailyVol/(callsDailyVol + putsDailyVol);
	prevPcOoiRatio = putsDailyOoi/(callsDailyOoi + putsDailyOoi);

	//////////////////////// get first day data on volumes /////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////


	while(++equityIndex < underlyer->getNbrRows()){ //increment before comparing, to start comparing from row 1.

		currDate = underlyer->getDate(equityIndex);

		if (nbrToLong - currLongPos > 0){ //I have to buy some stock

			if(currCash - (1+tCRatio)*(nbrToLong-currLongPos)*underlyer->getOpen(equityIndex) >= 0){ // I've go enough cash to commit
				currCash -= (1+tCRatio)*(nbrToLong-currLongPos)*underlyer->getOpen(equityIndex);
				currLongPos = nbrToLong;
			}
			else{
				nbrToLong = currLongPos + floor(currCash/((1+tCRatio)*underlyer->getOpen(equityIndex))); //buy as much as I can
				currCash -= (1+tCRatio)*(nbrToLong-currLongPos)*underlyer->getOpen(equityIndex);
				currLongPos = nbrToLong;
			}

		}
		else if (nbrToLong - currLongPos < 0){ // I have to sell some stock, currently only doing long only.
			currCash += (1-tCRatio)*(currLongPos - nbrToLong)*underlyer->getOpen(equityIndex);
			currLongPos = nbrToLong;
		}
		else{} // do nothing.

		//re-initialize values on new date
		callsDailyVol = 0;
		callsDailyOoi = 0;
		putsDailyVol = 0;
		putsDailyOoi = 0;
		//get calls daily volume and open interest for all options on given day.
		while (calls->getDate(callsPos) == currDate){ //while I am on one date
			callsDailyVol += calls->getVolume(callsPos);
			callsDailyOoi += calls->getOoi(callsPos);
			++callsPos;
			if(callsPos == calls->getNbrRows()) break;
		}

		//get puts daily volume and open interest for all options on given day.
		while (puts->getDate(putsPos) == currDate){ //while I am on one date
			putsDailyVol += puts->getVolume(putsPos);
			putsDailyOoi += puts->getOoi(putsPos);
			++putsPos;
			if(putsPos == puts->getNbrRows()) break;
		}

		currPcVolRatio = putsDailyVol/(callsDailyVol + putsDailyVol); //update pcVolRatio, wrong, actually want difference in volumes from one day to the other.
		currPcOoiRatio = putsDailyOoi/(callsDailyOoi + putsDailyOoi);

		//make trade decision based on pcVolRatio
		//start easy, only long, cannot short.

		if (currPcVolRatio - prevPcVolRatio < RATIODIFF){
			nbrToLong += floor((1-currPcVolRatio)*(currCash/((1+tCRatio)*underlyer->getClose(equityIndex))));
		}
		else if (currPcVolRatio - prevPcVolRatio > RATIODIFF)
			if(currLongPos > 0)
				nbrToLong = floor((currPcVolRatio)*currLongPos); //diminish part of stocks
			else{}
		else{
			if(currLongPos*underlyer->getClose(equityIndex) > currCash) //no clear sign and lots of cash in stocks
				nbrToLong = nbrToLong * 0.9; //diminish part of equity. 0.9 picked random
			else{} //do nothing.
		}


		results.push_back(currCash + currLongPos * underlyer->getClose(equityIndex));
		dataOut << currDate << "," << currCash + currLongPos* underlyer->getClose(equityIndex)
				<< "," << currCash << "," << currLongPos << "," << 0 << endl;
	}

	plotResults(underlyer->getDateColumnPtr(), &results);
	plotLogResults(underlyer->getDateColumnPtr(), &results);
	return 0;


	return 0;
}
Exemplo n.º 2
0
long optionsVolumeComp1(vector<Asset*>& assets, double startMoney){

	Asset* calls;
	Asset* puts;
	Asset* underlyer;
	const double RATIODIFF = 0.05;
	double tCRatio = 0.01; //records the transaction cost ratio
	if (assets.size() != 3){
		cerr << " Wrong number of objects to test optionsVolumeComp1" << endl;
		exit (EXIT_FAILURE);
	}

	if (assets.at(0)->getIsEquity() == 1){ //first object is Equity
		underlyer = assets.at(0);
		if(assets.at(1)->getIsCall() == 1){ //second object is calls
			calls = assets.at(1);
			puts = assets.at(2);
		}
		else{
			calls = assets.at(2);
			puts = assets.at(1);
		}
	}
	else if (assets.at(0)->getIsOption() == 1){
		if(assets.at(0)->getIsCall() == 1){
			calls = assets.at(0);
			if(assets.at(1)->getIsEquity() == 1){
				underlyer = assets.at(1);
				puts = assets.at(2);
			}
			else{
				underlyer = assets.at(2);
				puts = assets.at(1);
			}

		}
		else{
			puts = assets.at(0);
			if(assets.at(1)->getIsEquity() == 1){
				underlyer = assets.at(1);
				calls = assets.at(2);
			}
			else{
				underlyer = assets.at(2);
				calls = assets.at(1);
			}
		}
	}

	else{
		cerr << " Functions requires an equity, a  put and a call dataset to do analysis."
				"At least one is missing." << endl; //write using exception throwing rather than exit.
		exit (EXIT_FAILURE);
	}



	//we have the required types of data: perform back-test.
	//ooi is lagged by one day. Do not forget, that for any day. we get the
	//info on the following day, thus trading strategy must rely on
	//one day old information.
	//Equity information is contained in separate object.

	struct stat fStatus; //where all the output will be i for further analysis
	string outputFile = assets.at(0)->getWriteTo()+ "/" + "optionsVolumeComp1.csv";
	int thereOrNot = stat(outputFile.c_str(), &fStatus);
	ofstream dataOut(outputFile.c_str(), ios_base::out | ios_base::app); //append to file only will create file if not there
	if (thereOrNot == -1) //file not already created.
		dataOut << "Date," << "Capital," << "Cash," << "LongPos," << "ShortPos" << endl;
	else{}//do nothing


	double currCash = startMoney;
	deque<double>results;
	results.push_back(startMoney);
	double currLongPos = 0; //number of short positions
	double nbrToLong = 0; //number of shares to buy first thing in morning.
	double currShortPos = 0; //number of long positions (trying long only for now)
	double nbrToShort = 0; //number of shares to short first thing in morning.
	size_t equityIndex = 0;
	long currDate = underlyer->getDate(equityIndex);
	dataOut << currDate << "," << currCash + currLongPos* underlyer->getClose(equityIndex)
			<< "," << currCash << "," << currLongPos << "," << 0 << endl;

	size_t callsPos = 0;
	size_t putsPos = 0;
	double callsDailyVol = 0;
	double callsDailyOoi = 0;
	double putsDailyVol = 0;
	double putsDailyOoi = 0;
	double prevPcVolRatio = 0;
	double currPcVolRatio = 0;
	double prevPcOoiRatio = 0;
	double currPcOoiRatio = 0;

	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	//////////////////////// get first day data on volumes /////////////////////////////
	while (calls->getDate(callsPos) == currDate){
		callsDailyVol += calls->getVolume(callsPos);
		callsDailyOoi += calls->getOoi(callsPos);
		++callsPos;
		if(callsPos == calls->getNbrRows()) break;
	}

	//get puts daily volume and open interest for all options on given day.
	while (puts->getDate(putsPos) == currDate){ //while I am on one date
		putsDailyVol += puts->getVolume(putsPos);
		putsDailyOoi += puts->getOoi(putsPos);
		++putsPos;
		if(putsPos == puts->getNbrRows()) break;
	}

	prevPcVolRatio = putsDailyVol/(callsDailyVol + putsDailyVol);
	prevPcOoiRatio = putsDailyOoi/(callsDailyOoi + putsDailyOoi);

	//////////////////////// get first day data on volumes /////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////


	while(++equityIndex < underlyer->getNbrRows()){ //increment before comparing, to start comparing from row 1.

		currDate = underlyer->getDate(equityIndex);

		if (nbrToLong - currLongPos > 0){ //I have to buy some stock

			if(currCash - (1+tCRatio)*(nbrToLong-currLongPos)*underlyer->getOpen(equityIndex) >= 0){ // I've go enough cash to commit
				currCash -= (1+tCRatio)*(nbrToLong-currLongPos)*underlyer->getOpen(equityIndex);
				currLongPos = nbrToLong;
			}
			else{
				nbrToLong = currLongPos + floor(currCash/((1+tCRatio)*underlyer->getOpen(equityIndex))); //buy as much as I can
				currCash -= (1+tCRatio)*(nbrToLong-currLongPos)*underlyer->getOpen(equityIndex);
				currLongPos = nbrToLong;
			}

		}
		else if (nbrToLong - currLongPos < 0){ // I have to sell some stock, currently only doing long only.
			currCash += (1-tCRatio)*(currLongPos - nbrToLong)*underlyer->getOpen(equityIndex);
			currLongPos = nbrToLong;
		}
		else{} // do nothing.

		//re-initialize values on new date
		callsDailyVol = 0;
		callsDailyOoi = 0;
		putsDailyVol = 0;
		putsDailyOoi = 0;
		//get calls daily volume and open interest for all options on given day.
		while (calls->getDate(callsPos) == currDate){ //while I am on one date
			callsDailyVol += calls->getVolume(callsPos);
			callsDailyOoi += calls->getOoi(callsPos);
			++callsPos;
			if(callsPos == calls->getNbrRows()) break;
		}

		//get puts daily volume and open interest for all options on given day.
		while (puts->getDate(putsPos) == currDate){ //while I am on one date
			putsDailyVol += puts->getVolume(putsPos);
			putsDailyOoi += puts->getOoi(putsPos);
			++putsPos;
			if(putsPos == puts->getNbrRows()) break;
		}

		currPcVolRatio = putsDailyVol/(callsDailyVol + putsDailyVol); //update pcVolRatio, wrong, actually want difference in volumes from one day to the other.
		currPcOoiRatio = putsDailyOoi/(callsDailyOoi + putsDailyOoi);

		//make trade decision based on pcVolRatio
		//start easy, only long, cannot short.

		if (currPcVolRatio - prevPcVolRatio < RATIODIFF){
			nbrToLong += floor((1-currPcVolRatio)*(currCash/((1+tCRatio)*underlyer->getClose(equityIndex))));
		}
		else if (currPcVolRatio - prevPcVolRatio > RATIODIFF)
			if(currLongPos > 0)
				nbrToLong = floor((currPcVolRatio)*currLongPos); //diminish part of stocks
			else{}
		else{
			if(currLongPos*underlyer->getClose(equityIndex) > currCash) //no clear sign and lots of cash in stocks
				nbrToLong = nbrToLong * 0.9; //diminish part of equity. 0.9 picked random
			else{} //do nothing.
		}


		results.push_back(currCash + currLongPos * underlyer->getClose(equityIndex));
		dataOut << currDate << "," << currCash + currLongPos* underlyer->getClose(equityIndex)
				<< "," << currCash << "," << currLongPos << "," << 0 << endl;
	}

	plotResults(underlyer->getDateColumnPtr(), &results);
	plotLogResults(underlyer->getDateColumnPtr(), &results);
	return 0;
}