Programmieren in EViews Herbert Stocker Dezember 2008 Programme werden nicht im Workfile, sondern als eigenen Dateien mit der Erweiterung.prg gespeichert; d.h. Programmdateien müssen eigenständig geöffnet und gespeichert werden. Wird im Programm kein Workfile angegeben wird ein geöffneter Workfile als Default angenommen. In einem Programm können alle Befehle verwendet werden, die auch im Kommandofenster verwendet werden können (sowie einige zusätzliche), und dies mit der Befehls- oder der Objektmethode. Generell sollte der Objektmethode der Vorzug gegeben werden, da diese weniger fehleranfällig ist. Programmvariablen Innerhalb eines Programmes können lokale Programmvariablen angelegt werden. Programmvariablen sind lokal, d.h. werden nach Ende des Programms vergessen. Prinzipiell ist zwischen Numerische Programmvariablen und Stringvariablen zu unterscheiden. Numerische Programmvariablen beginnen immer mit einem Rufzeichen (!) und müssen nicht initialisiert werden, z.b.!counter = 1 Lokale Stringvariablen: Strings sind alphanumerische Zeichenketten, d.h. können aus Buchstaben und Zahlen bestehen. Strings können zwar manipuliert werden, aber mit Strings kann man nie rechnen. Stringvariablen beginnen in EViews mit einem %-Zeichen, z.b. %Country = Austria (der Inhalt von Stringvariablen ist Anführungszeichen einzuschließen). Zuweisungen In der Mathematik kennen wir das Gleichheitszeichen (=) als logischen Operator. Beim Programmieren wird das Gleichheitszeichen auch als Zuweisungszeichen verwendet, z.b. weist!i = 1 der numerischen Programmvariablen!i den Wert 1 zu. Zwei wichtige Elemente beim Programmieren sind Schleifen (z.b. for... und die Abfrage von logischen Bedingungen (if...then). For-Next Schleifen For-Next Schleifen sind eines der wichtigsten Konstrukte beim Programmieren. Zum Beispiel kann folgendermaßen programmiert werden: Kommentar: Summe von 1-10!sum = 0 for!j = 1 to 10!sum =!sum +!j scalar sum =!sum 10 Sum = j j=1 1
Da die numerische Programmvariable nach Beendigung des Programms verloren geht muss der Inhalt am Schluss in einen Skalar geschrieben werden. For-Next Schleifen können auch geschachtelt werden. Zum Beispiel kann folgendermaßen programmiert werden!sum = 0 for!i = 1 to 2 for!j = 2 to 4!sum =!sum + 2*!j +!i scalar sum =!sum 2 i=1 j=2 4 (2j + i) Wird der Name der Laufvariablen in geschwungene Klammern { } eingeschlossen kann der Inhalt der Laufvariablen direkt an einen Objektnamen angefügt werden, z.b. erzeugt for!j = 5 to 2 step -1 series x{!j} = gdp*1.05^!j die folgenden Befehle, die einzeln ausgeführt werden: series x5 = gdp*1.05^5 series x4 = gdp*1.05^4 series x3 = gdp*1.05^3 series x2 = gdp*1.05^2 For-Next Schleifen können auch über Stringvariablen ausgeführt werden, wobei der Name der Stringvariable wie üblich mit einem % beginnen muss. Zum Beispiel for %y gdp gnp ndp nnp equation {%y}trend.ls %y c {%y}(-1) trend führt folgende Befehle aus: equation gdptrend.ls gdp c gdp(-1) trend equation gnptrend.ls gnp c gnp(-1) trend equation ndptrend.ls ndp c ndp(-1) trend equation nnptrend.ls nnp c nnp(-1) trend Hier ist %y der Name der Stringvariablen, die über gdp gnp ndp und nnp läuft. gdp(-1) ist die um eine Zeitperiode verzögerte Variable gdp (time lag). if then Bedingungen Manchmal soll ein Teil des Programms nur ausgeführt werden, wenn eine Bedingung erfüllt ist. Dies wird durch den if...then --- Befehl ermöglicht. Die Syntax ist if [logische Bedingung] then [Befehle wenn die Bedingung wahr ist] Sollte z.b. gezählt werden, wie oft eine Variable exper den Wert Null hat, könnte dies (auf umständliche Weise) mit folgendem Programm geschehen: 2
!n = 0 for!i = 1 to @obs(exper) if exper(!i) = 0 then!n =!n + 1 scalar n =!n Mit exper(!i) wird auf das!i-te Element der Datenreihe exper zugegriffen. Außerdem wird hier ein zweiter Zähler!n angelegt, der jeweils um Eins erhöht wird (!n =!n + 1) wenn die Bedingung erfüllt ist. Man beachte, dass das Gleichheitszeichen hier einmal als logischer Operator (in der if-bedingung exper(!i) = 0) und einmal als Wertzuweisungszeichen (z.b. in!n =!n + 1) vorkommt. If-Bedingungen können auch für andere Zwecke verwendet werden, z.b. fragt das folgende Progrämmchen ab, ob ein Objekt mit dem Namen tab1 existiert, und löscht dieses Objekt falls es existiert: if @isobject("tab1") = 1 then delete tab1 Die EViews-Funktion @isobject(...) gibt den Wert 1 zurück falls das Objekt existiert und 0 sonst. Die logischen Bedingungen können mit and und/oder or erweitert werden: if!a>5 and!a<10 then smpl 1950:1 1970:1+!a Die If-Abfrage kann auch um einen else Teil erweitert werden, wobei die Befehle innerhalb des else-teils ausgeführt werden, wenn die Bedingung nicht wahr ist; z.b. if!scale > 0 then series newage = age/!scale else series newage = age Programm Argumente Programm Argumente sind spezielle Stringvariablen oder Parameter, die bei Aufruf eines Programms an das Programm übergeben werden können. Diese Stringvariablen oder Parameter werden einfach beim Aufruf des Programms durch Leerzeichen getrennt angefügt. run progname arg1 arg2... Im Programm selbst werden sie mit %0, %1, %2,... %9 in der Reihenfolge des Aufrufs angesprochen. Wenn wir z.b. ein Programm mit dem Namen prog1.prg haben, das aus einer einzigen Zeile scalar X = 2 * %0 + %1 besteht, so würde der Aufruf run prog1 5 3 dem Skalar X den Wert 13 (= 2 5 + 3) zuordnen. Beispiel: Das folgende Beispielsprogramm datacheck.prg dient dazu, sich einen schnellen Überblick über die einzelnen Datenreihen einer Regression zu verschaffen. Dazu muss zuerst dem Gleichungsobjekt ein Namen gegeben werden, und dieser Gleichungsname wird als Argument dem Programm übergeben. Daten einer Regression prüfen Aufruf: run datacheck eqnname {%0}.makeregs tmpgr erzeugt Regressoren-Gruppe freeze(_{%0}_stats) tmpgr.stats Tabelle mit Statistiken 3
show _{%0}_stats freeze(_{%0}_scat) tmpgr.scatmat Matrix mit Streudiagrammen show _{%0}_scat Der EViews-Befehl eqnname.makeregs groupname erzeugt eine Gruppe mit abhängiger und allen unabhängigen Variablen eines Equationobjekts (mit Ausnahme der Konstanten). Wenn dieses Programm den Namen datacheck.prg hat wird es mit run datacheck eqnname aufgerufen und erzeugt es eine Tabelle mit den deskriptiven Statistiken und Streudiagramme zwischen allen in der Gleichung vorkommenden Variablen. Output in Tabellen schreiben Sollte Text- und/oder Tabellenoutput bereits in EViews fertig aufbereitet werden, sodass er direkt in andere Anwendungen kopiert werden kann, so bieten sich dafür Tabellenobjekte an. Tabellen werden mit dem Befehl table(zeilen,spalten) tabname angelegt, wobei zeilen die Anzahl der Zeilen und spalten die Anzahl der Spalten ist. Sollten Texte und Zahlen in eine Zelle geschrieben werden muss die Zahl zuerst mit der Funktion @str(x) in eine String umgewandelt werden. Strings können mit +äneinander gekettet werden. Beispiel: table(2,1) mytab mytab(1,1) = "Meine erste Tabelle:" mytab(2,1) = "Das R2 ist " + @str(eq1.@r2) + ", der Standardfehler " + @str(eq1.@se) legt ein neues Tabellenobjekt mit 2 Zeilen, 1 Spalte und dem Namen mytab an, schreibt in die erste Zeile und Spalte Meine erste Tabelle: und in die zweite Zeile einen Text sowie das R 2 und den Standardfehler des Gleichungsobjekts eq1. Da numerische Variablen und Stringvariablen nie vermischt werden dürfen wird hier die numerische Variable eq1.@r2 mit der EViews-Funktion @str(...) in einen String umgewandelt. Aber selbstverständlich können Zellen auch numerische Variablen beinhalten. Programm-Beispiele Die folgenden Beispiele zeigen etwas komplexere Anwendungen. Berechnung von Wachstumsraten Das folgende Programm liest aus der Excel-Tabelle EVIEWS Growth GDPpC.xls 10 Variablen mit den GDP-Daten für 10 Länder ein, berechnet die Wachstumsraten, schreibt das Ergebnis in ein Tabellenobjekt mit dem Namen GrowthTab und zeigt dies an. Daten laden wfcreate(wf="growth") a 1975 2002 read(t=xls,t,d2) "EVIEWS_Growth_GDPpC.xls" 10 table(10,2) GrowthTab Tabelle, in die Output geschrieben wird GrowthTab(1,1) = "GDP Growth Rates: " 1. Zelle series Trend = @trend trend anlegen!i = 1 Zähler für Tabellenzeilen Begin der For-Schleife über Stringvariablen 4
for %y AUS AUT BEL CAN CHN DEU ITA NLD CHE USA!i =!i + 1 bei jedem Durchgang weiterzählen equation _tmp.ls @log({%y}) c Trend Gleichung schätzen GrowthTab(!i,1) = %y Land in Tabelle schreiben GrowthTab(!i,2) = (@exp(c(2)) - 1)*100 Wachstumsrate in Tabelle schreiben delete _tmp show GrowthTab Schleife Ende Lösche Gleichungsobjekt Zeige Ergebnis Eine einfache Monte Carlo Simulation Monte Carlo Simulationen hauptsächlich dazu, die die Eigenschaften von Schätzfunktionen zu eruieren. Das Grundprinzip von Monte Carlos Simulationen wurde bereits besprochen (siehe Manuskript Kapitel 2.3.3, Seite 39), deshalb hier nur sehr kurz: Das wahre Modell ist für den Forscher im Normalfall unbekannt, sonst müsste er es nicht schätzen. Die Idee von Monte Carlo Simulationen besteht darin, das wahre Modell vorzugeben, damit Daten zu erzeugen und zu prüfen, wie gut ein Schätzer das wahre Modell mit diesen Daten reproduziert. Wenn man dies sehr oft wiederholt kann man Mittelwert und Standardabweichung der Schätzer berechnen. Das wahre Modell im folgenden Beispiel ist Y i = β 0 +β 1 X i +u i mit β 0 = 2 und β 1 = 0.5 sowie u i = N(0, 1). Das Programm zieht 500 Stichproben, berechnet für jede dieser 500 Stichproben den Steigungskoeffizienten b 1 und schreibt diesen in einen Vektor VR, und gibt schließlich Statistiken und Histogramm davon aus (da das Histogramm nicht von Vektoren, sondern nur nur von Series ausgegeben werden kann, muss der Vektor zuerst mit dem Befehl mtos (matrix to series) in eine Datenreihe umgewandelt werden). wfcreate(wf="temp") u 1 25 Workfile anlegen (undated, 25 Obs.) vector(500) VR = na series X = @trend for!i = 1 to 500 series y = 2 + 0.5*X + @rnorm equation temp.ls Y c X VR(!i) = c(2) range 1 500 smpl @all mtos(vr,sr) SR.hist Vektor um Ergebnis zu speichern unabhängige Variable (Trend) Schleife, 1000mal durchlaufen wahres Modell + normalvert. ZV Anwendung von OLS Koeffizient in Vektor schreiben Ende der Schleife Workfile vergrößern sample anpassen Vektor in series umwandeln Histogramm anzeigen Rolling Regressions Zur Überprüfung der Stabilität der geschätzten Koeffizienten kann man Regressionen über unterschiedliche Subsamples rechnen und die geschätzten Koeffizienten vergleichen. Vorwiegend bei Zeitreihendaten fährt man manchmal mit einem Fenster fixer Breite über die Daten und schätzt für jedes Fenster eine Regression. Das folgende Programm legt zuerst Zufallsvariablen an (eine gleichverteilte Zufallsvariable zwischen 0 und 10 für X und einen normalverteilten Störterm für Y ), schätzt mit einer Fensterbreite von 100 die Regressionen, wobei das Fenster bei jedem Durchgang um Eins weiter rückt. 5
Monte Carlo Simulation Y = b0 + b1*x 0.52 0.51 0.50 0.49 0.48 0.47 10 20 30 40 50 60 70 80 90 100 Results for b1 Abbildung 1: Monte Carlo Simulation: Die ersten 100 Schätzungen für das wahre β 1 = 0.5 1600 1200 800 400 0 0.40 0.45 0.50 0.55 0.60 Series: OUT Sample 1 10000 Observations 10000 Mean 0.500259 Median 0.500608 Maximum 0.606847 Minimum 0.400228 Std. Dev. 0.027562 Skewness -0.029150 Kurtosis 2.938183 Jarque-Bera 3.008401 Probability 0.222195 Abbildung 2: Monte Carlo Simulation: Histogram (für 10,000 Stichprobenziehungen) Die für jedes Fenster geschätzten Steigungngskoeffizienten werden schließlich als Grafik angezeigt. This program runs rolling regressions, each with 100 observations, and creates a vector of rolling intercept coefficients. wfcreate(wf="rollreg") u 200 6
Here we make some random data series x = @runif(0,10) series y = 1 + 0.5*x + @rnorm We will put the slope estimates in a vector (results) vector (100) results equation eq1 for!i = 1 to 100 smpl!i 100+!i eq1.ls y c x results(!i) = c(2) smpl @all freeze(_graph) results.line _Graph.addtext(t) Estimates for b1, Rolling Regressions show _Graph Der OLS-Schätzer mit Matrix-Operatoren This will find a vector of coefficients two ways: the LS command and by basic matrix operations. wfcreate(wf="regress1") u 100 Create a workfile Generate the data we wish to regress We will regress y on x1, x2 and an intercept series x1= nrnd series x2 = nrnd series y = x1 + 3*x2 + nrnd first regressor second regressor dependent variable It is easiest to create a matrix from a group, group xgrp c x1 x2 c is the intercept Create the regressor matrix matrix x = @convert(xgrp) Generate the coefficient vector vector b=@inverse(@inner(x)) * @transpose(x)*@convert(y) Delete temporary variables delete xgrp x Estimate an equation to test against our coefficient vector equation lseqn.ls y c x1 x2 show lseqn show b Übung: Berechnen Sie die Summe aller geraden Zahlen von 1 100. (Hinweis: die EViews-Funktion @floor(variable) liefert den niedrigeren ganzahligen Wert, z.b. @floor(5/2) = 2) 7
Arbeiten mit Pages Die Excel Datei MonthlyQuarterly.xls enthält zwei Arbeitsblätter, das Blatt BIP mit Quartalsdaten für das österreichische BIP vom 1. Quartal 1996 bis zum 2. Quartal 2008, und das Blatt Arbeitslosenquote mit Monatsdaten der österreichischen Arbeitslosenrate (ALQ) von Jänner 1970 bis Oktober 2008. Die erste Zahl der Datenreihen steht in beiden Blättern in der Excel Zelle B2. Das folgende Programm liest beide Datenreihen in getrennte EViews pages ein, und kopiert die monatliche Datenreihe ALQ als Quartalsdaten von 1996:1 bis 2008:2 in das Blatt mit dem BIP ein, wobei quartalsweise der Mittelwert der monatlichen Arbeitslosenqote berechnet wird. cd "d:\home\lehre\oekono\skript\eviews" wfcreate(wf=myname,page=quarterly1) q 1996:1 2008:2 read(t=xls,b2,s=bip) QuarterlyMonthly.xls 1 pagecreate(page=monthly1) m 1970:1 2008:10 1 read(t=xls,b2,s=arbeitslosenquote) QuarterlyMonthly.xls 1 copy(smpl="1996:1 2008:2", c=mean) monthly1\alq quarterly1\ pageselect quarterly1 show BIP ALQ 8