Dies ist eine korrigierte Version des Programms:
df <- data.frame(type=c("C", "C"), marketV=c(1.1166, 1.911), S=c(20, 60), K=c(20, 56), T=c(0.333, 0.5))
IV <- function(df) {
# check if df has more then 1 row:
if (nrow(df)>1) { message("!! nrow(df)>1 !!"); return(NA) }
# Initializing of variables
r <- 0
sigma <- 0.3
sigma_down <- 0.001
sigma_up <- 1
count <- 0
type <- df$type; marketV <- df$marketV; S <- df$S; K <- df$K; T <- df$T
d1 <- (log(S/K) + (sigma^2/2)*T)/(sigma*sqrt(T))
d2 <- (log(S/K) - (sigma^2/2)*T)/(sigma*sqrt(T))
if(type=="C") {
V <- exp(-r*T)*(S*pnorm(d1) - K*pnorm(d2))
} else {
V <- exp(-r*T)*(K*pnorm(-d2) - S*pnorm(-d1)) }
difference <- V - marketV
# Root finding of sigma by Bisection method
while(abs(difference)>0.001 && count<1000) {
if(difference < 0) {
sigma_down <- sigma
sigma <- (sigma_up + sigma)/2
} else {
sigma_up <- sigma
sigma <- (sigma_down + sigma)/2
}
d1 <- (log(S/K) + (sigma^2/2)*T)/(sigma*sqrt(T))
d2 <- d1 - sigma*sqrt(T)
if(type=="C") {
V <- exp(-r*T)*(S*pnorm(d1) - K*pnorm(d2))
} else {
V <- exp(-r*T)*(K*pnorm(-d2) - S*pnorm(-d1)) }
difference <- V - marketV
count <- count + 1
}
if(count == 1000){
return(NA) # If sigma to satisfy Black76 price cannot be found
} else{
return(sigma)
}
}
sapply(split(df, seq(nrow(df))), IV)
Die Hauptsache ist, Zeile für Zeile durch den Datenrahmen laufen . Dies geschieht durch
sapply(split(df, seq(nrow(df))), IV)
In Ihrer ursprünglichen Funktion sind viele Fehler: der größte zugreift zu S
, K
und so weiter. Sie könnten die Werte aus dem Datenrahmen df
übernehmen. Aber tatsächlich haben Sie die Werte aus dem Arbeitsbereich übernommen! Ich korrigierte dies durch eine Neudefinition:
type <- df$type; marketV <- df$marketV; S <- df$S; K <- df$K; T <- df$T
ich einen Test für die Anzahl der Zeilen in df
eingefügt, so erhalten Sie:
> IV(df)
!! nrow(df)>1 !!
[1] NA
Hier ist eine aufgeräumt Version des Programms:
df <- data.frame(type=c("C", "C"), marketV=c(1.1166, 1.911), S=c(20, 60), K=c(20, 56), T=c(0.333, 0.5))
IV2 <- function(type, marketV, S, K, T) {
r <- 0; sigma <- 0.3
sigma_down <- 0.001; sigma_up <- 1
count <- 0
if(type=="C") {
f.sig <- function(sigma) {
d1 <- (log(S/K) + (sigma^2/2)*T)/(sigma*sqrt(T))
d2 <- d1 - sigma*sqrt(T)
exp(-r*T)*(S*pnorm(d1) - K*pnorm(d2)) - marketV
}
} else {
f.sig <- function(sigma) {
d1 <- (log(S/K) + (sigma^2/2)*T)/(sigma*sqrt(T))
d2 <- d1 - sigma*sqrt(T)
exp(-r*T)*(K*pnorm(-d2) - S*pnorm(-d1)) - marketV
}
}
ifelse(f.sig(sigma_down)*f.sig(sigma_up) < 0, uniroot(f.sig, c(sigma_down,sigma_up))$root, NA) # sigma
}
sapply(split(df, seq(nrow(df))), do.call, what="IV2")
'lapply (df, IV)'? – Tensibai
Sie definieren Ihre Argumente nicht in der richtigen Weise. Sie müssen darüber nachdenken, was Sie in Ihre Funktion eingeben (atm sieht so aus, als ob Sie den gesamten Datensatz eingeben möchten) und wie diese Eingabe in der Funktion verwendet werden soll. 'R' weiß nicht, dass die' S', 'K' und' T' innerhalb Ihrer Funktion Variablen der Eingabe sind. Ich habe nicht über die ganze Funktion geschaut, aber vielleicht versuche ich am Anfang der Funktion 'attach (df)' einzufügen und dann 'IV (yourdf)' aufzurufen. – LAP
Danke @jogo, du hast Recht. Dies wird nicht funktionieren. – LAP