等价于R中的句柄功能

问题描述 投票:1回答:1

我正在将一些代码从Matlab移至R,并且在特殊的handle函数中遇到了一些困难。这是我的Matlab代码:

function Application_ChFun
clear;close all;clc;warning('off');
StepsYr = 10;

%% --parameters-- %%
S0 = 1;   
r  = 0.0; 
t0 = 0;   
T2 = 5;

gamma = 0.5; 
kappa = 0.3; 
rho   = -0.6; 
vBar  = 0.05; 
v0    = 0.04; 

NoOfPaths = 5e4; 
NoOfSteps = StepsYr*T2;
%% --Define model-- %%
cf = @(u,T)ChFun(u, T, kappa,vBar,gamma,rho, v0, r);
Vc = @(t,x)MktFun(cf,t,x,log(S0));

% Define bump size
bump_T  = 1e-4;
bump_K  = @(T)1e-4;

% Define derivatives
dC_dT   = @(T,K) (Vc(T + bump_T,K) - Vc(T ,K)) /  bump_T;
dC_dK   = @(T,K) (Vc(T,K + bump_K(T)) - Vc(T,K - bump_K(T))) / (2 * bump_K(T));
d2C_dK2 = @(T,K) (Vc(T,K + bump_K(T)) + Vc(T,K-bump_K(T)) - 2*Vc(T,K)) / bump_K(T)^2;

t   = t0;
S = S0+zeros(NoOfPaths,1);

for i = 1:NoOfSteps

    if i==1
        t_adj = 1/NoOfSteps;
        t     = t_adj; 
    end       

    % AAA perfectly matches with the R equivalent, but AAB and AAC do not.
    AAA = dC_dT(t,S);
    AAB = dC_dK(t,S);
    AAC = d2C_dK2(t,S);
end 

function value = MktFun(cf,T,x,x0)
value = CM_Proxy(cf,T,x,x0);

function value = CM_Proxy(ChF,T,K,x0)
K(K<1e-5)=1e-5;

alpha   = 0.75; 
c       = 3e2;
N_CM    = 2^12;

eta    = c/N_CM;
b      = pi/eta;
u      = [0:N_CM-1]*eta;
lambda = 2*pi/(N_CM*eta);
i      = complex(0,1);

u_new = u-(alpha+1)*i; 
cf    = exp(i*u_new*x0).*ChF(u_new,T);
psi   = cf./(alpha^2+alpha-u.^2+i*(2*alpha+1)*u);

SimpsonW         = 3+(-1).^[1:N_CM]-[1,zeros(1,N_CM-1)];
SimpsonW(N_CM)   = 0;
SimpsonW(N_CM-1) = 1;
FFTFun           = exp(i*b*u).*psi.*SimpsonW;
payoff           = real(eta*fft(FFTFun)/3);
strike           = exp(-b:lambda:b-lambda);
payoff_specific  = spline(strike,payoff,K);
value = exp(-log(K)*alpha).*payoff_specific/pi;

function cf=ChFun(u, tau, kappa,vBar,gamma,rho, v0, r)
i     = complex(0,1);

D_1  = sqrt(((kappa -i*rho*gamma.*u).^2+(u.^2+i*u)*gamma^2));
g    = (kappa- i*rho*gamma*u-D_1)./(kappa-i*rho*gamma*u+D_1);    

C = (1/gamma^2)*(1-exp(-D_1*tau))./(1-g.*exp(-D_1*tau)).*(kappa-gamma*rho*i*u-D_1);
A = i*u*r*tau + kappa*vBar*tau/gamma^2 * (kappa-gamma*rho*i*u-D_1)-2*kappa*vBar/gamma^2*log((1-g.*exp(-D_1*tau))./(1-g));

cf = exp(A + C * v0);

其中MktFun是标准函数。当首先调用g=dC_dK(t,S)时,将评估bump_K(T),然后评估Vc(T,K + bump_K(T))Vc(T,K-bump_K(T))

在R中,我有以下内容:

Application_ChFun <- function(){

  StepsYr = 10

  ## --parameters-- ##
  S0 = 1  
  r  = 0.0 
  t0 = 0   
  T2 = 5

  gamma = 0.5 
  kappa = 0.3 
  rho   = -0.6   
  vBar  = 0.05  
  v0    = 0.04  

  NoOfPaths = 5e4 
  NoOfSteps = StepsYr*T2

  ## --Define model-- ##
  cf <- function(u,T) ChFun(u,T,kappa,vBar,gamma,rho, v0, r)
  Vc <- function(t,x) MktFun(cf,t,x,log(S0))

  # Define bump size
  bump_T = 1e-4
  bump_K <- function(T) 1e-4

  # Define derivatives
  dC_dT   <- function(T,K) (Vc(T + bump_T,K) - Vc(T ,K)) /  bump_T
  dC_dK   <- function(T,K) (Vc(T,K + bump_K(T)) - Vc(T,K - bump_K(T))) / (2 * bump_K(T))
  d2C_dK2 <- function(T,K) (Vc(T,K + bump_K(T)) + Vc(T,K - bump_K(T)) - 2*Vc(T,K)) / bump_K(T)^2

  t = t0
  S = S0+rep(0,NoOfPaths)

  for (i in 1:NoOfSteps){

    t_real = t

    if (i==1){
      t_adj = 1/NoOfSteps;
      t     = t_adj 
    }

    # AAA perfectly matches with the R's equivalent. But AAB and AAC do not.
    AAA = dC_dT(t,S) 
    AAB = dC_dK(t,S)
    AAC = d2C_dK2(t,S)

  }
}


MktFun <- function(cf,T,x,x0){
  return(CM_Proxy(cf,T,x,x0))
}

CM_Proxy <- function(ChF,T,K,x0){

  K[K<1e-5] = 1e-5

  alpha = 0.75 
  c = 3e2
  N_CM = 2^12

  eta = c/N_CM
  b = pi/eta
  u = (0:(N_CM-1))*eta
  lambda = 2*pi/(N_CM*eta)
  i = complex(real = 0, imaginary = 1)

  u_new = u - (alpha+1)*i # European call option.
  cf = exp(i*u_new*x0)*ChF(u_new,T)
  psi = cf/(alpha^2+alpha-u^2+i*(2*alpha+1)*u)

  SimpsonW  = 3+(-1)^(1:N_CM)-c(1,rep(0,N_CM-1))
  SimpsonW[N_CM] = 0
  SimpsonW[N_CM-1] = 1
  FFTFun = exp(i*b*u)*psi*SimpsonW
  payoff = Re(eta*fft(FFTFun)/3)
  strike = exp(seq(-b,b-lambda,lambda))
  K = as.vector(K)
  payoff_specific = stinepack::stinterp(strike,payoff,K)
  value = exp(-log(K)*alpha)*payoff_specific$y/pi

  return(value)
}

ChFun <- function(u, tau, kappa,vBar,gamma,rho, v0, r){

  i = complex(real = 0, imaginary = 1)

  D_1 = sqrt(((kappa - i*rho*gamma*u)^2 + (u^2+i*u)*gamma^2))
  g = (kappa - i*rho*gamma*u - D_1) / (kappa - i*rho*gamma*u + D_1)   

  C = (1/gamma^2)*(1-exp(-D_1*tau))/(1-g*exp(-D_1*tau))*(kappa-gamma*rho*i*u-D_1)
  A = i*u*r*tau + kappa*vBar*tau/gamma^2 * (kappa-gamma*rho*i*u-D_1) +
                                                      -2*kappa*vBar/gamma^2*log((1-g*exp(-D_1*tau))/(1-g))

  cf = exp(A + C * v0)

  return(cf)
}

问题在于,在这种情况下,g=dC_dK(t,S)直接调用Vc,而不是先调用bump_k(T)。有人可以提出解决方案吗?

r matlab functor handle
1个回答
0
投票

函数的评估顺序不一定要由内而外(如您所期望的那样),而是根据需要的顺序而定。 R尝试延迟执行操作,因此,如果您包含从未真正引用过的昂贵操作,则无法实现。

举这个例子:

f1 <- function(a) { message("f1"); a + 1; }
f2 <- function(b) { message("f2"); f1(b) + 2; }
f3 <- function(d) { message("f3"); f2(f1(d) + 3) / f2(f1(d) + 4); }
f3(2)
# f3
# f2
# f1
# f1
# f2
# f1
# f1
# [1] 0.9

f3被调用时,对f2的调用是下一个要评估的对象。首次调用f2(与f1(d)+3一起使用)时,将使用未经评估的参数调用f2。 [f2尝试使用其b后,才对其进行评估并调用f1

如果我在第一次调用f1时看到调用堆栈,那么我们会看到:

Browse[2]> where
where 1 at #1: f1(b)
where 2 at #1: f2(f1(d) + 3)
where 3 at #1: f3(2)

显示函数的顺序是先调用f3,然后调用f2,然后再调用f1

© www.soinside.com 2019 - 2024. All rights reserved.