Reaching given targets with a compiled model (code included)

For technical support, tips and tricks, suggestions, or any other information regarding the EViews model object.

Moderators: EViews Gareth, EViews Moderator

jlbrillet
Posts: 49
Joined: Mon Feb 16, 2009 6:03 am

Reaching given targets with a compiled model (code included)

Postby jlbrillet » Wed Dec 15, 2010 5:11 am

Hello,

Some time ago I presented a method which allows simulations to reach given targets for a set of endogenous variables , through the automatic computation of the same number of exogenous elements.

My post had very little success, which surprised me as I often met people who had trouble with this problem. Maybe I was not clear enough, I will rephrase the post.

One big advantage of this method is that it does not call for model redifinition. You can use the original compiled version. To switch to another instrument or target, you just have to change a name in one or two lines and run the program again.

To apply the method, what you have to do is give in a specific paragraph :

* The name of the model
* The sample period
* The list of the exogenized elements.
* The associated target values
* The list of exogenous instruments.

and include a specific generic program, good for any case.

The process can be repeated within the same simulation process. For instance, you might want to reach a large set of already available 2010 values, then make your 2011-2015 forecast reach a smaller set of targets.

This program is based on Newton's method. It works most of the time, provided the targets are reasonable and the instruments not too colinear. I use it in my work on various models and it saves me a lot of time.

It it does not work you can always go back to your usual technique. A friend of mine implemented the method in 15 minutes, without any help from me.


I include the program. What you just have to do is to replace the “solve” statement(s) in your main program by the following paragraph of EViews statements, in which you will include the requested information (see above).

At the end, this paragraph will “include” a generic EViews program (also provided) called “targetting” which must be available in your directory (do not make any changes).

I can also send you a paper describing the method.

Jean Louis Brillet.

THE PARAGRAPH

'*******************************************************************

' START OF THE TARGETTING PROCESS

'**********************************************************************


' Now we start creating the elements

' The starting and ending periods
' The name of the model
' The two lists of variables which change status
' The target values for the new exogenous

' They must be typed in the appropriate spaces

' in the lines showing : ***** User information ************

' No other editing is necessary

' We define the simulation periods

%date_1="starting date" ' ***** User information ************ Example : %date_1="2010Q3" (with quotes)
%date_2="ending date" ' ***** User information ************ Example : %date_2="2015Q4" (with quotes)

' We define the model name

%model= “model name1" ' ***** User information ************ Example : %model= “france_1" (with quotes)

' We define the lists of elements which change status
' exogenous to endogenous
' endogenous to exogenous
' The numbers must be the same

' If not, the program stops with a message

' For instance : f_crval : export/import ratio at current prices
' f_fcgp : budget deficit in GDP points
' f_unr : unemployment rate (0.xx)
' f_pfd : local demand deflator

' f_fdg : Government demand at constant prices
' f_scre : Social contributions rate for firms
' f_scrs : Social contributions rate for workers
' f_lg : Government employment

'***** User information ************ The list of new exogenous

group g_vexog1 list-of-instruments ' Example : group g_vexog1 f_fdg f_scre f_scrs f_lg (no quotes)

'***** User information ************ The list of targetted endogenous

group g_vendog1 list-of-instruments ' Example : group g_vendog1 f_crval f_fcgp f_unr f_pfd (no quotes)

'***** User information ************ The values of targetted endogenous

' For each target you must include a statement creating a “_star” variable. For instance

' genr f_crval_star=1 balanced trade balance
' genr f_fcgp_star=-3 3 points of GDP deficit
' genr f_unr_star=0.07 7% unemployment rate
' genr f_pfd_star=f_pfd*0.98 Deflator 2% lower than actual

' Finally, calling for the targetting algorithm

include targetting

'' *******************************************************************

' END OF THE TARGETTING PROCESS

' '**********************************************************************

Now the actual targetting program (NOT TO BE MODIFIED)
Just copy from the ***** line to the end of the message
Into a file called "targetting.prg"


' ***********************************************************************

' START OF The generic program for targetting

' It must be "included" after giving values to the requested parameters

' At the end of the process :


' The "actual" values of the endogenous will contain the solutions (the targets)
' The "actual" values of the endogenous will be set to the targetting values

' This means than a subsequent naked "solve" (no override or exclude, on the same period as the targetting process)
' will give the targets as a solution, in one iteration

' In case of problems, write to jlbrillet@yahoo.fr

' ------------------------------------------------------------------------------


' We copy the model into _model

copy {%model} _model

' We start with scenario "_z"

_model.scenario(n) "Scenario z"
_model.append assign @all _z
_model.solveopt(n=t m=10001 c=1e-8 o=g d=d)

' We define the sample range

if @isobject("_range") then
delete _range
endif

sample _range {%date_1} {%date_2}

smpl _range

' We solve the model once

_model.solve(n=t m=10002 c=1e-8 o=g d=d)

' We create a list of all the endogenous

_model.makegroup g_vendog @endog

' We set the "historical" values to the solution we obtained

for !i=1 to g_vendo.@count
%1=g_vendo.@seriesname(!i)
genr {%1}={%1}_z
next

tic ' Starting the stopwatch

' We delete Scenario 1 (it exists)

_model.scenario(d) "Scenario 1"

' We set the sample at the full range

smpl @first @last
genr _dum2=1


smpl _range

' We create a dummy variable for the full range
' anc compute the number of observations

if @isobject("_dum") then
delete _dum
endif

genr _dum=1

scalar _obsnb=@obssmpl

for !i=1 to g_vexog1.@count
vector(_obsnb) delv_{!i}
next


' nstar is the common number

scalar nstar=g_vexog1.@count

' The loop will run on all observations in the range

' The condition identifies the !iper th period in the sample
' for which a lag of !iper will produce an NA
' but not a lag of !iper+1


smpl @all
for !i=1 to g_vexog1.@count
%1=g_vexog1.@seriesname(!i)
genr {%1}_0={%1}
genr {%1}_cur={%1}
next

' Srat of the loop on periods

for !iper=1 to _obsnb
smpl _range if _dum(-!iper)=na and _dum(-!iper+1)<>na

' We build Scenario 0 as the base
' It will contain the current solution
' The associated suffix will be "_0"
' We declare all the overriden exogenous
' (with the currently best solution)

' (note : we start with a blank list and fill it one by one)

_model.scenario(n) "Scenario 0"

_model.append assign @all _0

_model.override
for !i=1 to g_vexog1.@count
%1=g_vexog1.@seriesname(!i)
_model.override(m) {%1}
next

' Now we create the alternate scenarios
' for computation of the Jacobian
' They are numbered 1 to nstar (here 2)
' The suffix is "_n"
' The exogenous are the same as Scenario 0

' Note : all exogenous have to be overriden
' but only one will change from the _0 value
' for a given scenario

for !i=1 to nstar
_model.scenario(n,a={!i},i="Scenario 0") Scenario {!i}
_model.append assign @all _{!i}
next

' Now we define the Jacobian

matrix(nstar,nstar) jacob


' print jacob

' Now we initialize the exogenous instruments
' used to reach the target

for !i=1 to g_vexog1.@count
%1=g_vexog1.@seriesname(!i)
genr {%1}_cur={%1}
genr {%1}_0={%1}
for !j=1 to g_vexog1.@count
genr {%1}_{!j}={%1}
next
next

' And the endogenous target variables

for !i=1 to g_vendog1.@count
%1=g_vendog1.@seriesname(!i)
genr {%1}_0={%1}_z
genr {%1}_cur={%1}_0
next

' We set the maximum number of iterations
' and the convergence criterion

scalar nitmax=20
scalar sconv=1e-6

' We initialize as control variables
' the number of iterations
' And the variable controlling the convergence

!niter=0
!iconv=0

' We double the éléments so they can be displayed

scalar niter=0
scalar iconv=0

' We display several éléments for control

' print g_vexog1 g_vendog1
' print *_cur *_star

'---------------------------------------------------------
' Now we start the loop
'---------------------------------------------------------

' It will run while convergence is not achieved
' and the maximum numbre of loops is not reached

while !niter<=nitmax and !iconv=0

' We increment the iteration counter

!niter=!niter+1
scalar niter=niter+1

' We test for convergence
' We suppose it is achieved (!iconv=1)
' Then we look at the relative difference
' between the present solution and the target
' for each targetted endogenous

' If the relative difference is higher than the criterion
' for any target
' convergence is not yet reached (!iconv=0)

!iconv=1
scalar iconv=1

for !j=1 to g_vendog1.@count
%1=g_vendog1.@seriesname(!j)

genr dele_{!j}=({%1}_star-{%1}_cur)/({%1}_cur+({%1}_cur=0))
stom(dele_{!j},delv_{!j},_range)

if @abs(delv_{!j}({!iper}))>sconv then
!iconv=0
scalar iconv=0
endif

next



' We display the differences

' print dele_*

' We compute the base solution
' defined as Scenario 0

_model.scenario "Scenario 0"
solve(m=1003) _model

' The solution values are set as current

for !i=1 to g_vendog1.@count
%1=g_vendog1.@seriesname(!i)
genr {%1}_cur={%1}_0
if niter=1 then
genr {%1}_base={%1}_0
endif
next

' We save the initial solution (for comparison with the shocked one later)

if niter=1 then
for !i=1 to g_vendo.@count
%1=g_vendo.@seriesname(!i)
genr {%1}_base={%1}_0
next
endif

' We display the current solution (exogenous + endogenous) and the targets

' print niter
' print *_cur *_star

' Now we compute the Jacobian
' We start a loop on the shocked instruments

for !i=1 to g_vexog1.@count

' For each exogenous, we compute the whole set of overriding instruments
' shocking only the current one by 0.01 %
' while the others keep their base value
' This is necessary to implement the current changes

for !j=1 to g_vexog1.@count
%2=g_vexog1.@seriesname(!j)
smpl @all
genr {%2}_{!i}={%2}_cur
smpl _range if _dum(-!iper)=na and _dum(-!iper+1)<>na
genr {%2}_{!i}={%2}_cur*(1+.001*({!i}={!j}))
next

' We solve the model under Scenario !i

_model.scenario Scenario {!i}
solve(m=1004) _model

' Now we compute the relative change in the target endogenous
' This will give a column of the Jacobian matrix

for !j=1 to g_vendog1.@count
%2=g_vendog1.@seriesname(!j)
genr _z=({%2}_{!i}-{%2}_cur)/({%2}_cur+({%2}_cur=0))/0.001
stom(_z,_zscal,_range)
jacob(!j,!i)=_zscal({!iper})
next

next

' This ends the computation of the Jacobian

' We compute its inverse

' print jacob

matrix jacob_inv=@inverse(jacob)

' print jacob_inv

' We apply to each exogenous a change equal to
' the inverse of the jacobian
' times the remaining error.

' This gives a new solution for the exogenous
' We start the process again until convergence (hopefully)

for !i=1 to g_vexog1.@count
%1=g_vexog1.@seriesname(!i)
genr {%1}_old={%1}_cur
for !j=1 to g_vendog1.@count
%2=g_vendog1.@seriesname(!j)
genr {%1}_cur={%1}_cur+{%1}_old*jacob_inv(!i,!j)*({%2}_star-{%2}_cur)/({%2}_cur+({%2}_cur=0))
next
genr {%1}_{!i}={%1}_cur
genr {%1}_0={%1}_cur
genr delxc_{%1}=({%1}_cur-{%1}_old)/{%1}_old
genr delxt_{%1}=({%1}_cur-{%1})/{%1}
next
' print delxc_*
' print delxt_*
wend

for !i=1 to g_vendo.@count
%1=g_vendo.@seriesname(!i)
genr delf_{%1}=100*({%1}_0-{%1}_base)/({%1}_base+({%1}_base=0))
next

' we set the endogenous to the solution values

for !i=1 to g_vendo.@count
%1=g_vendo.@seriesname(!i)
genr {%1}={%1}_0
next

for !i=0 to g_vendog1.@count
_model.scenario(d) Scenario !i
next

next ' end of the loop on periods

' We restore the full sample

smpl _range
for !i=1 to g_vexog1.@count
%1=g_vexog1.@seriesname(!i)
genr {%1}={%1}_cur
next

toc ' Stopping the stopwatch. EViews displays the time the computation took

'***************************************************************************

' End of targetting program
' The "actual" values of the endogenous contain the solutions (the targets)
' The "actual" values of the instruments are set to the targetting values

'***************************************************************************
Last edited by jlbrillet on Mon Dec 27, 2010 2:52 am, edited 5 times in total.

trubador
Did you use forum search?
Posts: 1518
Joined: Thu Nov 20, 2008 12:04 pm

Re: Reaching fixed targets (using the same compiled model)

Postby trubador » Wed Dec 15, 2010 7:07 am

I believe you would have received more response, if you had posted your program. You can encrypt the program, if you do not want to share its details.


Return to “Models”

Who is online

Users browsing this forum: No registered users and 17 guests