⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cooneyexcel.cpp

📁 financal instrument pricing using c
💻 CPP
字号:

#include "defs.h"
#include "CooneyExcel.hpp"
#include <cstdio>

struct StartOle {
    StartOle() { CoInitialize(NULL); }
    ~StartOle() { CoUninitialize(); }
} _inst_StartOle;

CooneyExcel::CooneyExcel()
{ // Default constructor
}

CooneyExcel::CooneyExcel(int rows, int columns): m_matrix(rows, columns)
{ // Construct
}

CooneyExcel::~CooneyExcel()
{ // Destructor
}

void CooneyExcel::AddSerie(double* data, int row)
{ // Add serie to matrix

	int column;
	int index=0;
	int maxcolumn=m_matrix.MaxColumnIndex();
	int pointerindex=0;
	for (column=m_matrix.MinColumnIndex(); column<=maxcolumn; column++, index++)
	{
		m_matrix(row, column)=data[index]; 
	}
}

// Global functions for sending vectors and matrices to Excel
bool CooneyExcel::ToExcel(struct Params& param, struct SolSettings& setting)
{ // Send numeric matrix to excel

	try
	{
		// Create an Excel object
		ExcelDriver xl;

		// Open Excel and add workbook
		xl.OpenExcel();
		xl.AddWorkbook();

		// Fill data
		FillNormal(param, setting, xl);
		FillDelta1(param, setting, xl);
		FillDelta2(param, setting, xl);
		FillDelta3(param, setting, xl);

		// Create a chart
		xl.CreateChart(1, m_matrix.Rows(), m_matrix.Columns(), ChartTitleText(param, setting), CategoryText(param), ValueText(param));
		xl.SetActiveSheet("Sheet1");
		xl.CreateChart(param.NT+3, m_matrix.Rows(), m_matrix.Columns()-2, ChartTitleText(param, setting) + "\n(Centered differences)", CategoryText(param), "Delta");
		xl.SetActiveSheet("Sheet1");
		xl.CreateChart(2*(param.NT+2)+1, m_matrix.Rows(), m_matrix.Columns()-2, ChartTitleText(param, setting) + "\n(Approximation to second derivative)", CategoryText(param), "Gamma");
		xl.SetActiveSheet("Sheet1");
		xl.CreateChart(3*(param.NT+2)+1, m_matrix.Rows(), m_matrix.Columns()-1, ChartTitleText(param, setting) + "\n(One-side difference)", CategoryText(param), "Epsilon");
		xl.SetActiveChart(ValueText(param));
		return true;
	}
	catch(_com_error&)
	{ // For now ignore error

		return false;
	}
}

void CooneyExcel::FillNormal(struct Params& param, struct SolSettings& setting, ExcelDriver& xl)
{ // Fill Excel sheet with normal data

	try
	{
		// Send matrix to active excel sheet
		int rowIndex;
		int columnIndex;
		int row;
		int column;

		// First fill the range
		xl.FillRange(param.h, param.S, param.NS-1, 1);

		// Get active sheet and its range
		Excel::_WorksheetPtr pSheet=xl.Application()->ActiveSheet;
		Excel::RangePtr pRange=pSheet->Cells;

		// Get max row and column index
		int maxRow=m_matrix.MaxRowIndex();
		int maxColumn=m_matrix.MaxColumnIndex();

		// Send all matrix values to the sheet
		// values begin in row 2
		row=2;
		for (rowIndex=m_matrix.MinRowIndex(); rowIndex<=maxRow; rowIndex++)
		{ // Do all rows

			// Fill series (row) text
			((Excel::RangePtr)pRange->Item[(double)row][(double)1])->Value=SerieText(param, row-1).c_str();
			
			// Do columns. Values start in column 2
			column=2;
			for (columnIndex=m_matrix.MinColumnIndex(); columnIndex<=maxColumn; columnIndex++)
			{ // Fill all columns
	
				((Excel::RangePtr)pRange->Item[(double)row][(double)column])->Value=(double)m_matrix(rowIndex, columnIndex);
				column++;
			}
			row++;
		}
	}
	catch(_com_error&)
	{ // For now ignore error
	}
}

void CooneyExcel::FillDelta1(struct Params& param, struct SolSettings& setting, ExcelDriver& xl)
{ // Fill Excel sheet with delta data 1

	try
	{
		// Send matrix to active excel sheet
		int rowIndex;
		int columnIndex;
		int row;
		int column;
		int serie;
		double val;

		// First fill the range. 0 is not calculated and the first and the last do not have the required neighbour
		xl.FillRange(2*param.h, param.S-param.h, param.NS-1-2, param.NT+3);

		// Get active sheet and its range
		Excel::_WorksheetPtr pSheet=xl.Application()->ActiveSheet;
		Excel::RangePtr pRange=pSheet->Cells;

		// Get max row and column index
		int maxRow=m_matrix.MaxRowIndex();
		int maxColumn=m_matrix.MaxColumnIndex();

		// Send all matrix values to the sheet
		// values begin in row param.NT+4
		row=param.NT+4;
		serie=1;
		for (rowIndex=m_matrix.MinRowIndex(); rowIndex<=maxRow; rowIndex++, serie++)
		{ // Do all rows

			// Fill series (row) text
			((Excel::RangePtr)pRange->Item[(double)row][(double)1])->Value=SerieText(param, serie).c_str();
			
			// Do columns. Values start in column 2
			column=2;
			for (columnIndex=m_matrix.MinColumnIndex()+1; columnIndex<maxColumn; columnIndex++)
			{ // Fill all columns
	
				val=(m_matrix(rowIndex, columnIndex+1)-m_matrix(rowIndex, columnIndex-1)) / (2*param.h);
				((Excel::RangePtr)pRange->Item[(double)row][(double)column])->Value=val;
				column++;
			}
			row++;
		}

	}
	catch(_com_error&)
	{ // For now ignore error
	}
}

void CooneyExcel::FillDelta2(struct Params& param, struct SolSettings& setting, ExcelDriver& xl)
{ // Fill Excel sheet with delta data 2

	try
	{
		// Send matrix to active excel sheet
		int rowIndex;
		int columnIndex;
		int row;
		int column;
		int serie;
		double val;

		// First fill the range. 0 is not calculated and the first and the last do not have the required neighbour
		xl.FillRange(2*param.h, param.S-param.h, param.NS-1-2, 2*(param.NT+2)+1);

		// Get active sheet and its range
		Excel::_WorksheetPtr pSheet=xl.Application()->ActiveSheet;
		Excel::RangePtr pRange=pSheet->Cells;

		// Get max row and column index
		int maxRow=m_matrix.MaxRowIndex();
		int maxColumn=m_matrix.MaxColumnIndex();

		// Send all matrix values to the sheet
		// values begin in row param.NT+4
		row=2*(param.NT+2)+2;
		serie=1;
		for (rowIndex=m_matrix.MinRowIndex(); rowIndex<=maxRow; rowIndex++, serie++)
		{ // Do all rows

			// Fill series (row) text
			((Excel::RangePtr)pRange->Item[(double)row][(double)1])->Value=SerieText(param, serie).c_str();
			
			// Do columns. Values start in column 2
			column=2;
			for (columnIndex=m_matrix.MinColumnIndex()+1; columnIndex<maxColumn; columnIndex++)
			{ // Fill all columns
	
				val=(m_matrix(rowIndex, columnIndex+1) - 2*m_matrix(rowIndex, columnIndex) + m_matrix(rowIndex, columnIndex-1)) / (param.h*param.h);
				((Excel::RangePtr)pRange->Item[(double)row][(double)column])->Value=val;
				column++;
			}
			row++;
		}

	}
	catch(_com_error&)
	{ // For now ignore error
	}
}

void CooneyExcel::FillDelta3(struct Params& param, struct SolSettings& setting, ExcelDriver& xl)
{ // Fill Excel sheet with delta data 3

	try
	{
		// Send matrix to active excel sheet
		int rowIndex;
		int columnIndex;
		int row;
		int column;
		int serie;
		double val;

		// First fill the range. 0 is not calculated and the first does not have the required neighbour
		xl.FillRange(2*param.h, param.S-param.h, param.NS-1-1, 3*(param.NT+2)+1);

		// Get active sheet and its range
		Excel::_WorksheetPtr pSheet=xl.Application()->ActiveSheet;
		Excel::RangePtr pRange=pSheet->Cells;

		// Get max row and column index
		int maxRow=m_matrix.MaxRowIndex();
		int maxColumn=m_matrix.MaxColumnIndex();

		// Send all matrix values to the sheet
		// values begin in row param.NT+4
		row=3*(param.NT+2)+2;
		serie=1;
		for (rowIndex=m_matrix.MinRowIndex(); rowIndex<=maxRow; rowIndex++, serie++)
		{ // Do all rows

			// Fill series (row) text
			((Excel::RangePtr)pRange->Item[(double)row][(double)1])->Value=SerieText(param, serie).c_str();
			
			// Do columns. Values start in column 2
			column=2;
			for (columnIndex=m_matrix.MinColumnIndex(); columnIndex<maxColumn; columnIndex++)
			{ // Fill all columns
	
				val=(m_matrix(rowIndex, columnIndex+1) - m_matrix(rowIndex, columnIndex)) / (param.h);
				((Excel::RangePtr)pRange->Item[(double)row][(double)column])->Value=val;
				column++;
			}
			row++;
		}

	}
	catch(_com_error&)
	{ // For now ignore error
	}
}

std::string CooneyExcel::SerieText(struct Params& param, int serie)
{ // Determine the series text from the parameter object and the current series
  // First serie=1
// TODO: Invent a better double to string conversion

	std::string result;
	double val;
	char str[256];

	val=(serie-1)*param.k;

	// Convert serie value to string
	sprintf(str, "t=%f", val);
	return (result + std::string(str));
}


std::string CooneyExcel::ChartTitleText(struct Params& param, struct SolSettings& setting)
{ // Determine the chart title text. eg. K=50, t=0.4, ...

	std::string result;
	char str[256];

	// Determine scheme
	switch (setting.scheme)
	{
		case EXACT:
			result=result + "Exact solution";
			break;
		case IMP:
			result=result + "Fully implicit scheme";
			break;
		case DUFF:
			result=result + "Fitted Duffy scheme";
			break;
		case CN:
			result=result + "Crank-Nicholson scheme";
			break;
		case FITTCN:
			result=result + "Fitted Crank-Nicholson scheme";
			break;
		default:
			result=result + "Unknown scheme";
			break;
	}
	
	// Determine method
	switch (setting.method)
	{
		case ITER:
			result=result + " - Iterative BiCGSTAB solver\n";
			break;
		case BALA:
			result=result + " - Direct Balayage solver\n";
			break;
		default:
			result=result + "\n";
			break;
	}

	// Determine parameters
	sprintf(str, "%.4f", param.K);
	result=result + "K=" + std::string(str) + ", ";


	sprintf(str, "%.4f", param.rate);
	result=result + "r=" + std::string(str) + ", ";

	sprintf(str, "%.4f", param.sigma);
	result=result + "sigma=" + std::string(str) + ", ";

	return result.substr(0, result.size()-2);
}

std::string CooneyExcel::CategoryText(struct Params& param)
{ // Determine the category text from the parameter object

	return "Stock price (S)";
}

std::string CooneyExcel::ValueText(struct Params& param)
{ // Determine value text

	switch (param.contract)
	{
	case EUROCALL:
		return "European Call Value";
		break;
	case EUROPUT:
		return "European Put Value";
		break;
	case AMERCALL:
		return "American Call Value";
		break;
	case AMERPUT:
		return "American Put Value";
		break;
	default:
		return "Unknown";
		break;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -