Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
braverock
GitHub Repository: braverock/portfolioanalytics
Path: blob/master/src/residualcokurtosisMF.c
1433 views
1
2
#include <R.h>
3
#include <Rinternals.h>
4
5
SEXP residualcokurtosisMF(SEXP NN, SEXP sstockM2, SEXP sstockM4, SEXP bbetacov){
6
/*
7
arguments
8
NN : integer, number of assets
9
sstockM2 : vector of length NN, 2nd moment of the model residuals
10
sstockM4 : vector of length NN, 4th moment of the model residuals
11
bbetacov : vector of length NN * NN, beta and factor covariance
12
13
Note that this function was orignally written in C++ (using Rcpp) by
14
Joshua Ulrich and re-written using the C API by Ross Bennett
15
*/
16
17
// // declare pointers for the vectors
18
double *stockM2, *stockM4, *betacov;
19
20
// Do I need to protect these if they are function arguments?
21
// use REAL() to access the C array inside the numeric vector passed in from R
22
stockM2 = REAL(sstockM2);
23
stockM4 = REAL(sstockM4);
24
betacov = REAL(bbetacov);
25
26
// Coerce length one R vector into C scalar
27
int N = asInteger(NN);
28
29
// Allocate and initialize matrix values to 0
30
// Do I need to fill the matrix with zeros here?
31
SEXP M4MF = PROTECT(allocMatrix(REALSXP, N, N*N*N));
32
double *rM4MF = REAL(M4MF);
33
// Note that the matrix is stored in column-major order and is represented
34
// as a 1-dimensional array. Access the element in X(row, col) with:
35
// element = row + column * nrows
36
// outer loop over the columns and inner loop down the row
37
for (int jj = 0; jj < N*N*N; jj++) {
38
for (int ii = 0; ii < N; ii++) {
39
rM4MF[ii + jj * N] = 0.0;
40
}
41
}
42
43
// Rcpp declarations
44
// NumericVector stockM2(sstockM2);
45
// NumericVector stockM4(sstockM4);
46
// NumericVector betacov(bbetacov);
47
// int N = as<int>(NN);
48
// NumericMatrix M4MF(N, pow(N,3));
49
50
double kijkl = 0.0;
51
int pos = 0;
52
53
for(int i=0; i<N; i++) {
54
for(int j=0; j<N; j++) {
55
for(int k=0; k<N; k++) {
56
for(int l=0; l<N; l++) {
57
// in the general case: i, j , k and l are all different
58
kijkl = 0;
59
// if at least one of them are equal:
60
if( (i==j) || (i==k) || (i==l) || (j==k) || (j==l) || (k==l) ) {
61
if( (i==j) && (i==k) && (i==l) ) {
62
// These are the kurtosis estimates of the individual assets: 6 bi S bi E[ei^2] + E[ei^4]
63
// this is element i,i in the cov, therefore in the vectorized form it is i*N+i
64
pos = i*N+i;
65
kijkl = 6*betacov[pos]*stockM2[i]+stockM4[i];
66
} else {
67
if( ((i==j) && (i==k)) || ((i==j) && (i==l)) || ((i==k) && (i==l)) || ((j==k) && (j==l)) ) {
68
// 3 indices are identical
69
if( (i==j) && (i==k) ) {
70
// all indices are the same except l: 3 biSbl E[ei^2]
71
pos = i*N+l;
72
kijkl = 3*betacov[pos]*stockM2[i];
73
} else
74
if( (i==j) && (i==l) ) {
75
// all indices are the same except k: 3 biSbk E[ei^2]
76
pos = i*N+k;
77
kijkl = 3*betacov[pos]*stockM2[i];
78
} else
79
if( (i==k) && (i==l) ) {
80
// all indices are the same except j: 3 biSbj E[ei^2]
81
pos =i*N+j;
82
kijkl = 3*betacov[pos]*stockM2[i];
83
} else
84
if( (j==k) && (j==l) ) {
85
// all indices are the same except i: 3 biSbi E[ei^2]
86
pos =j*N+i;
87
kijkl = 3*betacov[pos]*stockM2[j];
88
}
89
}
90
else {
91
if( ((i==j) && (k==l)) || ((i==k) && (j==l)) || ((i==l) && (j==k)) ) {
92
// kiijj = E[ U[,i]^2*U[,j]^2 ] = r5*sqrt( vm4[i]*vm4[j] )
93
if( (i==j) && (k==l) ) {
94
// biSbi E[ek^2] + bkSbk E[ei^2] + E[ei^2]E[ek^2]
95
pos = i*N+i;
96
kijkl = betacov[pos]*stockM2[k];
97
pos = k*N+k;
98
kijkl = kijkl + betacov[pos]*stockM2[i]+stockM2[i]*stockM2[k];
99
} else
100
if( (i==k) && (j==l) ) {
101
// biSbi E[ej^2] + bjSbj E[ei^2] + E[ei^2]E[ej^2]
102
pos =i*N+i;
103
kijkl = betacov[pos]*stockM2[j];
104
pos = j*N+j;
105
kijkl = betacov[pos]*stockM2[i]+stockM2[i]*stockM2[j];
106
} else
107
if( (i==l) && (j==k) ) {
108
// biSbi E[ej^2] + bjSbj E[ei^2] + E[ei^2]E[ej^2]
109
pos =i*N+i;
110
kijkl = betacov[pos]*stockM2[j];
111
pos = j*N+j;
112
kijkl = kijkl + betacov[pos]*stockM2[i]+stockM2[i]*stockM2[j];
113
}
114
} else {
115
if( i==j ) {
116
// bkSbl E[ei^2]
117
pos = k*N+l;
118
kijkl = betacov[pos]*stockM2[i];
119
} else
120
if( i==k ) {
121
// bjSbl E[ei^2]
122
pos = j*N+l;
123
kijkl = betacov[pos]*stockM2[i];
124
} else
125
if( i==l ) {
126
// bjSbk E[ei^2]
127
pos = j*N+k;
128
kijkl = betacov[pos]*stockM2[i];
129
} else
130
if( j==k ) {
131
// biSbl E[ej^2]
132
pos = i*N+l;
133
kijkl = betacov[pos]*stockM2[j];
134
} else
135
if( j==l ) {
136
// biSbk E[ej^2]
137
pos = i*N+k;
138
kijkl = betacov[pos]*stockM2[j];
139
} else
140
if( k==l ) {
141
// biSbj E[ek^2]
142
pos = i*N+j;
143
kijkl = betacov[pos]*stockM2[k];
144
}
145
}
146
}
147
} // no kurtosis estimates of individual assets
148
} // at least one of them are not equal
149
// i denotes the subcomoment matrix
150
//M4MF(k,i*pow(N,2)+j*N+l) = kijkl;
151
// Element = row + column * nrows
152
rM4MF[k + (i * N * N + j * N + l) * N] = kijkl;
153
} // loop l
154
} // loop k
155
} // loop j
156
} // loop i
157
UNPROTECT(1);
158
return M4MF;
159
}
160