gtmvn.gms : Demonstrate the use of numpy.multivariate_normal on stock return data using Transfer

Description

Use the GAMS Transfer method toDense and setRecords to work with
"number only" numpy.array to utilitze powerful numpy methods like
multivariate_normal to generate samples for a multivariate normal
distribution. Historic stock return data is used to build up the
covariance and mean data required by numpy.multivariate_normal method.


Category : GAMS Data Utilities library


Main file : gtmvn.gms   includes :  gtmvn.gms  stockdata.csv

$title Demonstrate the use of numpy.multivariate_normal on stock return data using Transfer (gtmvn,SEQ=143)

$onText
Use the GAMS Transfer method toDense and setRecords to work with
"number only" numpy.array to utilitze powerful numpy methods like
multivariate_normal to generate samples for a multivariate normal
distribution. Historic stock return data is used to build up the 
covariance and mean data required by numpy.multivariate_normal method.
$offText

Sets
   dates                    'dates'
   stocks                   'stocks';

Table price(dates<,stocks<) 'daily price'
$onDelim
$include stockdata.csv
$offDelim
;

Sets
   dp(dates)                 'all but first date';
Parameters
   return(dates,stocks)      'daily return'
   mean(stocks)              'expected daily return'
   cov(stocks,stocks)        'covariance matrix';
Alias (dates,d), (stocks,s,sp);

dp(dates) = ord(dates)>1;

return(dp(d),s) = log(price(d,s)) - log(price(d-1,s));
mean(s) = sum(dp, return(dp,s))/card(dp);
cov(s,sp) = sum(dp, (return(dp,s) - mean(s))*(return(dp,sp) - mean(sp))) / (card(dp)-1);

* 100 samples from the multivariate normal distribution represent 100 days of stock returns
$if not set NDAYS $set NDAYS 100
Set ds                    'simulated days' / d1*d%NDAYS% /;
Parameter mvn(stocks,ds)  'simulated daily stock returns based on a multivariate normal';

embeddedCode Python:
import gamstransfer as gt
from numpy.random import default_rng

nr = default_rng(0) # set static seed to avoid that repeated call produce different random sequences
m = gt.Container(gams.db)
cov = m.data["cov"].toDense()
mu = m.data["mean"].toDense()
mvn = nr.multivariate_normal(mu, cov, size=%NDAYS%, method='cholesky')
m.data["mvn"].setRecords(mvn.T)
m.write(gams.db, ["mvn"])
endEmbeddedCode mvn
display mvn;