1
- export simulate, forecast_quantiles
1
+ export simulate, forecast
2
2
3
3
mutable struct Forecast{T <: AbstractFloat }
4
- quantiles:: Matrix{T}
5
- scenarios:: Matrix{T}
4
+ observation_quantiles:: Matrix{T}
5
+ observation_forecast:: Vector{T}
6
+ observation_scenarios:: Matrix{T}
7
+ parameter_quantiles:: Array{T, 3}
8
+ parameter_forecast:: Matrix{T}
9
+ parameter_scenarios:: Array{T, 3}
6
10
end
7
11
8
12
"""
@@ -20,19 +24,29 @@ function simulate(series::Vector{T}, gas::Model{D, T}, H::Int, S::Int;
20
24
# Filter params estimated on the time series
21
25
params = score_driven_recursion (gas, series; initial_params = initial_params)
22
26
biggest_lag = number_of_lags (gas)
23
- params_simulation = params[(end - biggest_lag): (end - 1 ), :]
27
+ n_params = num_params (D)
28
+ params_simulation = params[(end - biggest_lag + 1 ): end , :]
24
29
# Create scenarios matrix
25
- scenarios = Matrix {T} (undef, H, S)
30
+ observation_scenarios = Matrix {T} (undef, H, S)
31
+ parameter_scenarios = Array {T, 3} (undef, H, n_params, S)
26
32
for scenario in 1 : S
27
- sim, param = simulate_recursion (gas, H + biggest_lag + 1 ; initial_params = params_simulation)
28
- scenarios[:, scenario] = sim[biggest_lag + 2 : end ]
33
+ # Notice that we know the parameter time_varying parameters for T + 1
34
+ # So the last initial_params is already a part of the future simulation
35
+ # And we must take the
36
+ sim, param = simulate_recursion (gas, H + biggest_lag; initial_params = params_simulation)
37
+ observation_scenarios[:, scenario] = sim[biggest_lag+ 1 : end ]
38
+ # The first param is known
39
+ parameter_scenarios[1 , :, scenario] = params_simulation[end , :]
40
+ # The last param (param[end, :]) is actually in a time step bigger
41
+ # than H
42
+ parameter_scenarios[2 : end , :, scenario] = param[biggest_lag+ 1 : end - 1 , :]
29
43
end
30
- return scenarios
44
+ return observation_scenarios, parameter_scenarios
31
45
end
32
46
33
47
34
48
"""
35
- forecast_quantiles (series::Vector{T}, gas::Model{D, T}, H::Int; kwargs...) where {D, T}
49
+ forecast (series::Vector{T}, gas::Model{D, T}, H::Int; kwargs...) where {D, T}
36
50
37
51
Forecast quantiles for future values of a time series by updating the GAS recursion `H` times and
38
52
using Monte Carlo method as in Blasques, Francisco, Siem Jan Koopman,
@@ -49,17 +63,40 @@ By default this method uses the `stationary_initial_params` method to perform th
49
63
score driven recursion. If you estimated the model with a different set of `initial_params`
50
64
use them here to maintain the coherence of your estimation.
51
65
"""
52
- function forecast_quantiles (series:: Vector{T} , gas:: Model{D, T} , H:: Int ;
53
- initial_params:: Matrix{T} = stationary_initial_params (gas),
54
- quantiles:: Vector{T} = T .([0.025 , 0.5 , 0.975 ]), S:: Int = 10_000 ) where {D, T}
66
+ function forecast (series:: Vector{T} , gas:: Model{D, T} , H:: Int ;
67
+ initial_params:: Matrix{T} = stationary_initial_params (gas),
68
+ quantiles:: Vector{T} = T .([0.025 , 0.5 , 0.975 ]), S:: Int = 10_000 ) where {D, T}
55
69
56
- scenarios = simulate (series, gas, H, S; initial_params = initial_params)
57
- return Forecast (get_quantiles (quantiles, scenarios), scenarios)
70
+ observation_scenarios, parameter_scenarios = simulate (series, gas, H, S;
71
+ initial_params = initial_params)
72
+ return Forecast (
73
+ get_quantiles (quantiles, observation_scenarios),
74
+ mean (observation_scenarios, dims = 2 )[:],
75
+ observation_scenarios,
76
+ get_quantiles (quantiles, parameter_scenarios),
77
+ mean (parameter_scenarios, dims = 3 )[:, :, 1 ],
78
+ parameter_scenarios
79
+ )
58
80
end
59
81
60
- function get_quantiles (quantile_probs :: Vector{T} , scenarios:: Matrix{T} ) where T
61
- @assert all ((quantile_probs .< 1.0 ) .& (quantile_probs .> 0.0 ))
62
- unique! (sort! (quantile_probs ))
63
- quantiles = mapslices (x -> quantile (x, quantile_probs ), scenarios; dims = 2 )
82
+ function get_quantiles (quantiles_probs :: Vector{T} , scenarios:: Matrix{T} ) where T
83
+ @assert all ((quantiles_probs .< 1.0 ) .& (quantiles_probs .> 0.0 ))
84
+ unique! (sort! (quantiles_probs ))
85
+ quantiles = mapslices (x -> quantile (x, quantiles_probs ), scenarios; dims = 2 )
64
86
return quantiles
65
87
end
88
+
89
+ function get_quantiles (quantiles_probs:: Vector{T} , scenarios:: Array{T, 3} ) where T
90
+ @assert all ((quantiles_probs .< 1.0 ) .& (quantiles_probs .> 0.0 ))
91
+ unique! (sort! (quantiles_probs))
92
+ quantiles_per_parameter = Array {T, 3} (undef,
93
+ size (scenarios, 1 ),
94
+ size (scenarios, 2 ),
95
+ length (quantiles_probs)
96
+ )
97
+ for j in 1 : size (scenarios, 2 )
98
+ quantiles_per_parameter[:, j, :] = mapslices (x -> quantile (x, quantiles_probs),
99
+ scenarios[:, j, :]; dims = 2 )
100
+ end
101
+ return quantiles_per_parameter
102
+ end
0 commit comments