Let’s turn the GAS on

It’s time to present a new alteration of my investment strategy. In doing so, I take use of a model that I have been aiming to include ever since the very start of this project. Namely, the generalized autoregressive sore model, or GAS. 

The idea is to use GAS in combination with the parametric portfolio policy and thereby obtain more dynamic or time-varying values of theta to determine the asset weights. I will soon show you how to do so in practice, and I will also show that this yields good potential for higher returns. But first and foremost, here follows some more theoretical details concerning GAS.


I. Generalized Autoregressive Score (GAS)

In short, I use GAS for modelling dynamic variables (i.e., dynamic values of theta) via functions of lagged and predetermined variables. This is probably best expressed in the equation below.

Omega (ω) stands for the long run or unconditional mean. Hence, this is the value that theta is supposed to converge towards in the long run. Beta (β) is the persistency parameter, which is basically telling the model how much it should continue to believe in its previous theta. The last parameter, alpha (α), can be seen as a sort of learning rate. Alpha plays a key role in updating the dynamic values of theta given the driving variable of the scaled score function (s). 


For combining GAS with the parametric portfolio policy, I define the scaled score function using the investor utility according to the following expressions. 

When assuming “unit” scaling, St=1, this implies that my scaled score function is nothing but the partial derivative of the one-month investor utility with respect to the theta of each month. 


One of the fundamental differences between GAS and the original parametric portfolio policy is that instead of using an optimizing objective to estimate theta (as further explained in A few simple rows), I here estimate omega, beta and alpha, which are all three used as building blocks for deriving the dynamic values of theta. 

With that said, I estimate the parameters in accordance with the expression below. 

That should be enough theoretical details so let’s move on to the practice. 


II. Practical implementation with Python

I will first show code-wise how to implement GAS into my current investment strategy (i.e., the static parametric portfolio policy using past trading volume, or dolvol, as a single asset characteristic). I will then show and discuss the performance of a few alternative dynamic strategies in comparison with the static policies from Why Dolvol and Beta?

For this purpose, I start by reading in and calculating the necessary data and variables as well as splitting my dataset into two batches for training and evaluation.

This should all look very similar to the initial steps in Why Dolvol and Beta?


Next, I define the function for the one-month investor utility and its corresponding partial derivative with respect to the theta of each month. As explained previously, this derivative, dj, represents the scaled score function within GAS.  

To be clear, t in jac(t, i) stands for the theta of each month, meanwhile, i stands for the specific month within the training period. Additionally, dj = grad(jac, 0) ensures that I take the derivative with respect to theta rather than with respect to time.  


I now have all that I need to build the optimizing GAS function for estimating the parameters omega, beta, and alpha. 

You will notice some similarities between this optimization and the one presented in A few simple rows. For instance, the asset weights, portfolio return and utility are modelled in a very similar way as before, and at the end of that day, I still want to optimize the mean investor utility over the period as stated by return - np.mean(u)

You will also notice that I use the training batch of our dataset, denoted as N1, dolz1, r1, etc. since I want to evaluate the out-of-sample performance at a later stage. 

The most fundamental difference within this optimization, however, is that I estimate three separate parameters, p[0], p[1], and p[2], which are then used for obtaining an array of dynamic thetas. Meaning thetas that are allowed to take different values each month. 

I run the optimization as stated above twice. First using x0 = [0.0, 0.98, 10] and second using x0 = [-0.688, 0.98, 10], where -0.688 is nothing but the estimated value of omega from the first stage. I do this to help the model begin with a more “reasonable” starting value for its long-run mean. 


The estimated omega, beta, and alpha arising from this optimization are presented below. These parameters are now going to be used to estimate the dynamic values of theta for the evaluation period.  

 

Moving on to the out-of-sample evaluation, I start by defining omega, beta and alpha given the previously estimated parameters.

 

I also need to define a new scaled score function using the dataset in the evaluation batch.

 

Whit this, I can then easily obtain the dynamic values of theta for the period using the following rows.

Where tet = gas(res.x, True)[-1] states that I want to use the last value of theta from the training period as a starting point.


Now, I have finally managed to end up with a simple array of dynamic values of theta as illustrated below. 

For interested readers, I have also added the time series of thetas obtained within the training period. 


And with this, it is quite easy to obtain the asset weights, given a monthly investment budget of SEK 5k, and the corresponding portfolio returns as follows. 

 


III. Performance evaluation

For the performance part, I have created two additional dynamic strategies using (i) momentum as a single asset characteristic, Mom (Dynamic), and (ii) both dolvol and momentum as asset characteristics, Dolvol + Mom (Dynamic). 

The dynamic values of theta, corresponding asset weights, and portfolio returns for these strategies have been obtained almost identically to the Dolvol (Dynamic) strategy as shown above. Why, for brevity, I don’t show how to build these two strategies code-wise within this post. 

In comparison, I have also included the performance of the three static strategies using (i) dolvol as a single asset characteristic, Dolvol (Static), (ii) both dolvol and momentum as asset characteristics, Dolvol + Mom (Static), and (iii) momentum as a single asset characteristic, Mom (Static). Which all three are presented in Why Dolvol and Beta?.


The performance of these six competing strategies, measured as the abnormal returns of the Fama and French five-factor model, is illustrated below. 


The dynamic strategies seem to do notably well, being superior compared to their static counterparts. Most striking is the Dolvol + Mom (Dynamic) strategy with an abnormal return of +1.82%. 

The same pattern can also be seen when looking at the Sharpe ratio of each strategy.

 

To summarize, I’m really excited by the results that I have obtained today. In particular, the dynamic strategy using both dolvol and momentum seems like a very promising candidate for my investment strategy when moving forward to future investments. I also do plan to show you the full details of this specific strategy in time. 

Comments