【C#】14. printOneExcel在Excel裡作圖 & 利率插值計算(線性)
阿新 • • 發佈:2019-01-08
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">今天主要寫寫怎麼用Visual Studio在Excel裡面做圖(chart),網上有很多人都討論過這個問題,但我覺得這裡還是寫一下C# for financial markets裡面怎麼寫的,因為我覺得這個做出來的比較好。</span>
首先看一下chart在excel裡面的結構位置:
這裡作圖主要用的就是ChartWizard,但是我剛開始做出來的圖巨醜無比。。。而且還不對,不知道為什麼,型別已經設定成XY散點圖,但是畫出來還是這幅尿性。。
後來經過書中的提示,我實現了這個函式,於是duang地一下,做出來了一張很唯美的chart!!!
// Excel作圖 【更新】2015/3/10 public void CreateChart<T>(Vector<T> x, Vector<T> y, string title, string horizontal, string vertical, string legend) { try { // Add sheet. Excel.Workbook pWorkbook; Excel.Worksheet pSheet; if (pExcel.ActiveWorkbook == null) { pWorkbook = (Excel.Workbook)InvokeMethodInternational(pExcel.Workbooks, "Add", Excel.XlWBATemplate.xlWBATWorksheet); pSheet = (Excel.Worksheet)pWorkbook.ActiveSheet; } else { pWorkbook = pExcel.ActiveWorkbook; pSheet = (Excel.Worksheet)InvokeMethodInternational(pWorkbook.Worksheets, "Add", Type.Missing, Type.Missing, 1, Type.Missing); } // Add row labels + values. int sheetColumn = 1; int sheetRow = 1; //列印X列 ToSheetVertical(pSheet, sheetRow, sheetColumn, horizontal, x); //列印Y列 ToSheetVertical(pSheet, sheetRow, sheetColumn + 1, vertical, y); // 在工作簿中增加圖表Chart(XY點圖) Excel.Chart chart = pWorkbook.Charts.Add(Type.Missing, Type.Missing, Type.Missing, Type.Missing) as Excel.Chart; Excel.Range range = (Excel.Range)pSheet.get_Range("A2","B" + (x.Length+1).ToString() ); chart.ChartWizard(range, Excel.XlChartType.xlXYScatterLinesNoMarkers, 1, Excel.XlRowCol.xlColumns, 1, 0, true, title, horizontal, vertical, Type.Missing); chart.SeriesCollection(1).Name = legend; } catch (Exception e) { Console.WriteLine("Exception: " + e); } }
class test { static void Main(string[] args) { Vector<double> t = new Vector<double>(new double[] { 0.1, 1, 4, 9, 20, 30 }, 0); Vector<double> r = new Vector<double>(new double[] { 0.081, 0.07, 0.044, 0.07, 0.04, 0.03 }, 0); LinearInterpolator myInterpolatorH = new LinearInterpolator(t, r); // Create the abscissa values f (hard-coded for the moment) int M = 299; Vector<double> term = new Vector<double>(M, 1); term[term.MinIndex] = 0.1; double step = 0.1; for (int j = term.MinIndex + 1; j <= term.MaxIndex; j++) { term[j] = term[j - 1] + step; } Vector<double> interpolatedlinear = myInterpolatorH.Curve(term); ExcelMechanisms exl = new ExcelMechanisms(); exl.printOneExcel<double>(term, interpolatedlinear, "Linear Interpolated Curve", "time", "Interest Rate", "Interpolated Interest Rate"); Console.Read(); }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UserDefinedDataEXP
{
//點列
public class Pair <T>
{
public T first;
public T second;
public Pair (T First, T Second)
{
this.first = First;
this.second = Second;
}
}
//雙線插值
public class BilinearInterpolator
{
private Vector<double> x1Arr;
private Vector<double> x2Arr;
private NumericMatrix<double> matVals;
private int N1;
private int N2;
//找出x1Arr中小於或者等於x的index
//找出x2Arr中小於或者等於y的index
public Pair<int> findAbscissa (double x,double y)
{
int firstIndex = 0;
int secondIndex = 0;
for (int i = 0; i <= N1-1; i++)
{
if (x1Arr[i]<=x && x<=x1Arr[i+1])
{
for (int j = 0; j <= N2 - 1; j++)
{
if (x2Arr[j] <= y && y <= x2Arr[j + 1])
{
return new Pair<int>(firstIndex, secondIndex);
}
secondIndex++;
}
}
firstIndex++;
}
return null;
}
//構造器
public BilinearInterpolator(Vector<double> x1arr, Vector<double> x2arr, NumericMatrix<double> gridValues)
{
this.x1Arr = x1arr;
this.x2Arr = x2arr;
N1 = x1arr.Length - 1;
N2 = x2arr.Length - 1;
matVals = gridValues;
}
//返回(x,y)上的值!
public double Solve(double x, double y)
{
Pair<int> p = findAbscissa(x, y);
int i = p.first;
int j = p.second;
// 4 box points, create variables for readability (see Wiki)
double Q11 = matVals[i, j]; double Q22 = matVals[i + 1, j + 1];
double Q12 = matVals[i, j + 1]; double Q21 = matVals[i + 1, j];
double x1 = x1Arr[i]; double x2 = x2Arr[i + 1];
double y1 = x2Arr[j]; double y2 = x2Arr[j + 1];
double factor = 1.0 / ((x2 - x1) * (y2 - y1));
return (Q11 * (x2 - x) * (y2 - y) + Q21 * (x - x1) * (y2 - y) + Q12 * (x2 - x) * (y - y1) + Q22 * (x - x1) * (y - y1)) * factor;
}
//根據輸入的(x,y)點列集,給出插值後的Surface
public NumericMatrix<double> Surface(Vector<double> x1arr, Vector<double> x2arr)
{
NumericMatrix<double> result=new NumericMatrix<double>(x1arr.Length, x1arr.Length);
for (int i = x1arr.MinIndex; i <= x1arr.MaxIndex; i++)
{
for (int j = x2arr.MinIndex; j <= x2arr.MaxIndex; j++)
{
result[i, j] = Solve(x1arr[i], x2arr[j]);
}
}
return result;
}
public NumericMatrix<double> Surface()
{ // Create the interpolated surface, MEMBER DATA AS ABSCISSAE
return Surface(x1Arr, x2Arr);
}
}
// LinearInterpolator【更新】2015/3/10
public class LinearInterpolator
{
public Vector<double> t;
public Vector<double> observedRate;
public LinearInterpolator(Vector<double> t, Vector<double> ObservedRate)
{
this.t = t;
this.observedRate = ObservedRate;
}
public Vector<double> Curve(Vector<double> term)
{
int size = term.Length;
Vector<double> result = new Vector<double>(term.Length,term.MinIndex);
for (int i =term.MinIndex ; i <=term.MaxIndex; i++)
{
if (term[i]<=t[t.MinIndex])
{
result[i] = observedRate[observedRate.MinIndex];
}
else if (term[i]>=t[t.MaxIndex])
{
result[i] = observedRate[observedRate.MaxIndex];
}
else
{
for (int j = t.MinIndex; j <=t.MaxIndex-1; j++)
{
if (term[i] > t[j] && term[i] < t[j + 1]) { result[i] = ((term[i] - t[j + 1]) * observedRate[j] + (t[j] - term[i]) * observedRate[j + 1]) / (t[j] - t[j + 1]); }
}
}
}
return result;
}
}
}