2017-01-26 1 views
0

Ich versuche mein eigenes erstes Projekt in R zu erstellen, habe aber einen Roadblock gefunden.Benutzerdefinierter Funktionseingang, um jede Reihe von Datenrahmen zu loopen

Ich habe einen Datenrahmen wie unten, wo jede Zeile Dataset einer finanziellen Option darstellt.

type <- c("C", "C") 
marketV <- c(1.1166, 1.911) 
S <- c(20, 60) 
K <- c(20, 56) 
T <- c(0.333, 0.5) 
df <- data.frame(type, marketV, S, K, T) 

Ich habe eine benutzerdefinierte Funktion dieses Datenrahmens als eine Eingabe zu nehmen und funktioniert gut, wenn der Datenrahmen eine Zeile lang ist. Ich bin mir jedoch nicht sicher, wie meine Funktion alle Datenrahmenzeilen durchläuft und für alle ein Ergebnis liefert.

Ich bin neu in R, also bin ich mir nicht sicher, ob ich eine 'for' Schleife herumspielen oder herumspielen sollte, oder wenn es eine einfache Syntaxantwort gibt. Ich will einfach, dass die Funktion das df als Eingabe nimmt, aber wiederhole ihre Berechnung für n Zeile und erzeuge n Ergebnisse. Vielen Dank für die Hilfe im Voraus.

Mein aktueller Funktionscode für eine df mit 1 Zeile unten als Referenz:

+0

'lapply (df, IV)'? – Tensibai

+0

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

+0

Danke @jogo, du hast Recht. Dies wird nicht funktionieren. – LAP

Antwort

2

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") 
Verwandte Themen