Epanechnikov Kernschätzung

  • Excel

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von Nordring.

    Epanechnikov Kernschätzung

    Hi zusammen!

    Ich sollte die Epanechnikov Kernschätzung für eine Reihe von Renditen berechnen. Folgende Formel dient als Vorlage:

    k(z)=Summe t=1 bis n f(rt, z)*(3/(4nb))

    wobei gilt: f(rt, z)= 1-((z-rt)/b) falls z-b < rt < z+b, ansonsten = 0

    z ist die Stelle der Auswertung, n ist die Anzahl Daten (Renditen), b ist die Bandweite (als Standard 1.06sigma*n^-0.2)

    Die Funktion sollte vom Typ "Function Kernel(data As Range, bins As Range, Optional bandwidth As Double)" sein. bins ist der Datensatz mit Punkten (z) an denen ausgwertet werden sollte.

    data erstreckt sich über die Felder A8:A206, bins über L8:L58

    Der von mir geschriebene Code funktioniert nicht, ich erhalte eine #WERT Fehlermeldung. Wo ist der Fehler? Danke fürs aushelfen...

    Visual Basic-Quellcode

    1. Option Base 1
    2. Option Explicit
    3. Function kernel(data As Range, bins As Range, Optional bandwidth As Double)
    4. Application.Volatile
    5. Dim einzeldichte As Double, dichte As Double, result() As Double
    6. Dim rt As Integer, n As Integer, nbins As Integer, z As Integer
    7. n = data.Rows.Count
    8. nbins = bins.Rows.Count
    9. ReDim result(1, nbins)
    10. If IsMissing(bandwidth) Then
    11. bandwidth = 1.06 * WorksheetFunction.StDev(data) * n ^ (-0.2)
    12. End If
    13. For z = 1 To nbins
    14. For rt = 1 To n
    15. If Cells(7 + z, 12) - bandwidth < Cells(7 + rt, 1) < Cells(7 + z, 12) + bandwidth Then
    16. einzeldichte = 1 - ((Cells(7 + z, 12) - Cells(7 + rt, 1)) / bandwidth) ^ 2
    17. Else
    18. einzeldichte = 0
    19. End If
    20. dichte = dichte + einzeldichte
    21. Next rt
    22. result(1, z) = dichte * (3 / (4 * n * bandwidth))
    23. Next z
    24. kernel = result
    25. End Function
    Du hast vergessen den Wert für die Funktion zu definieren:

    Function kernel(data As Range, bins As Range, Optional bandwidth As Double) as Double
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „INOPIAE“ ()

    Danke für den Input.

    Es handelt sich aber um eine Array Function. Da müsste meiner Meinung nach der Typ der Function nicht deklariert werden, sondern zum Schluss "kernel" einen Array - in meinem Fall "result" - zugewiesen werden. Oder liege ich da falsch?
    Eine Funktion kann man so als Double-Array deklarieren:

    Visual Basic-Quellcode

    1. Function kernel(...) As Double()




    Vielleicht ist ja die Tatsache, dass du ein Array zurückgibst, die Erklärung für #WERT!. Wenn ich beispielsweise "=B2:B10" eingebe, kommt als Ergebnis auch #WERT!.

    Was genau gibst du denn als Formel in die Tabelle ein?
    Nochmals danke für die Vorschläge!

    Zu "Double()" - ändert leider nichts. Ich bekomme immer noch die Fehlermeldung #WERT!. Im Excel Spreadsheet gebe ich die Formel wie folgt ein: =kernel(A8:A206;L8:L58) und natürlich mit CTRL-Shift-Enter abschicken. A8:A206 sind 199 Aktienrenditen, L8:L58 sind die Mittelpunkte für die Kernschätzung und erstrecken sich in 1%-Schritten von -25% bis +25%.

    Zum Vorschlag mit "1 to 1" und "1 to nbins" - habe ich dies nicht bereits mit dem Präfix Option Base 1 erledigt? Ich habe es trotzdem versucht, scheint aber auch nicht zu funktionieren.

    Sorry, irgendwie ist der Wurm drin. Anyone?
    schon irgendwie lustig, da bastelt man an seiner "Finance mit Excel" Aufgabe, hat ne Lösung, ist sich aber unsicher, füttert google mit "epanechnikov" und der 3. Treffer ist einer ausm Kurs mit dem selben Problem :D

    also des option base 1 is erst ma beinahe zwingend, damit ersparst du dir viel mühseliges. nicht vergessen, alle schleifen immer bei 1 anfangen.. das mit dem Function kernel(..) as double() kannst du rauslöschen, brauchst du nicht.
    das array result hast du allerdings als reihe deklariert. bei uns in der aufgabe ist jedoch die zielausgabe in spaltenform angegeben. also
    ReDim result(nbins, 1)
    ansonsten hab ich so ziemlich das selbe wie du, einfach ein par dinge bischen anders geschrieben. also anders formuliert, aber die funktion sollte den selben wert zurück geben wie bei dir. also schonmal beruhigend für mich (und für dich ;) )

    einzig: in der z-schleife (Zeile 18 - 28), müsstest du da nicht jedesmal die dichte wieder auf 0 setzen? weil sonst hast du ja in der letzten zeile den wert 1 .. das ist so bisschen das was mich verwirrt und wo ich nicht weiss, ob meine lösung stimmt ...


    ps: Cheffe sagte zwar, Gruppenarbeit ist verboten, aber schätze ma das fällt noch nicht unter Gruppenarbeit, oder?

    #Nachtrag
    Du adressierst deine Zellen immer mittels Cells(x,y). Das macht deine Funktion ziemlich unflexibel, da sie limitiert ist auf eben genau die erste spalte ab Zeile 8 bis irgendwas und die Spalte 12 (L). Ich würde wennschon mittels data(n, 1) resp bins(z, 1) zugreifen. sieht besser aus und machts flexibler ;)
    Tja, so trifft man sich wieder!

    Die Sache im Nachtrag habe ich bereits geändert, war in der ersten Version so, aber merci für die Anmerkung!

    Dass ich den Array result falschrum definiert habe ist mir nicht aufgefallen, typischer copy-paste fehler (Var-Covar Matrizze lässt grüssen). Danke! Ich werds ändern, hoffe das klappt dann. Mit auf null-zurücksetzen habe ich mich auch schon gefragt und mit jemandem darüber diskutiert. Ich sollte es wohl jeweils zurücksetzen... Try and error.
    ich hab ma versucht deine Funktion (mit meinen Bemerkungen umgesetzt) zum laufen zu bringen, aber aus mir unerklärlichen Gründen erhalte ich als Ausgabe Werte zwischen -4000 und 4000, also extremst zu hoch. Selbst wenn ich die dichte jedesmal wieder auf 0 setze..
    sieht die lösung bei dir in etwa richtig aus? Hast du eine Ahnung, in welcher Grössenordnung denn die Zellenwerte überhaupt sein sollten?
    Meine Schwanken von 0 (Zelle O-56 )bis 12.7284 (Zelle O-34). Die Summe der Zellen in der Spalte 0 beträgt bei mir 103.1595 .. hat die Summe der Zelleninhalte überhaupt etwas auszusagen? .. irgendwie sind mir die Werte von der Funktion noch etwas unklar was genau die Ausdrücken...
    Mein Kernel-output (der ja automatisch in den Graph eingefügt wird) ist jedenfalls (mit kleinen Ausreissern) fast deckungsgleich mit der Grünen linie .. ist das ein gutes zeichen?

    ps, schreib mir ma ne PM, dann weiss ich wer du bist (keine angst, ich bin nicht der Prof, der dich verpetzt :D)
    Deine Wert scheinen mir vernünftig - im Beriech z=1% hats ja ne Menge Renditen. Deshalb ist da der Wert der Kerndichte wohl am höchsten. Die Summe sagt nicht zwingend viel aus und wenn der Plot sich fast genau deckt ist ja sowieo alles in Butter!

    Man, man, wo habe ich den Bock geschossen?

    Grundschulstoff

    Na bravo, das ist Grundschulstoff: Division durch Null ist nicht erlaubt.

    Ich hab den Fehler nun selbst gefunden. Meine "If IsMissing etc." ist falsch aufgestellt und wird als Null interpretiert. Somit dividiere ich am Schluss der Funktion durch Null, was mir logischerweise die tolle #WERT! Meldung bescherrt. So einfach ist's.

    Danke für all den Support :thumbsup: , ich bastle die Sache nun wieder im Stillen weiter.
  • 2 Benutzer haben hier geschrieben