Repository: statsmodels/statsmodels

Issue:
Question about `VAR` model
Based on the [tutorial](https://www.statsmodels.org/stable/vector_ar.html) on `var` model, I used, to add an `exog` during training, at the procedure of `forecast`, I met 
```sh
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 0, the array at index 0 has size 5 and the array at index 1 has size 1.
``` 

What should be the format of `exog_future`? Am I giving the `exog` the right format?
```py
import numpy as np
import pandas
import statsmodels.api as sm
from statsmodels.tsa.api import VAR
from statsmodels.tsa.base.datetools import dates_from_str
    
mdata = sm.datasets.macrodata.load_pandas().data
dates = mdata[['year', 'quarter']].astype(int).astype(str)
    
quarterly = dates["year"] + "Q" + dates["quarter"]
quarterly = dates_from_str(quarterly)
mdata = mdata[['realgdp','realcons','realinv']]
mdata.index = pandas.DatetimeIndex(quarterly)

data = np.log(mdata).diff().dropna()  

model = VAR(endog = data.iloc[:,:2], exog = data.iloc[:, 2])
results = model.fit(maxlags=15, ic='aic')
lag_order = results.k_ar
results.forecast(y = data.values[-lag_order:, :2], steps = 5, exog_future = data.iloc[-lag_order:, 2])
```


Discussion:
Seems I need to make sure if I want 5 predictions, then `exog_future.shape[1]==5` is `True`
```py
n = 10
model = VAR(endog = data.iloc[:,:2][:-n], exog = data.iloc[:, 2][:-n])

results = model.fit(maxlags=15, ic='aic')
type(results)
lag_order = results.k_ar

data.values[:, :2][-10:]
results.forecast(y = data.values[-lag_order:, :2], steps = n, exog_future = data.values[-n:, 2])
```
If the docstring doesn't say that, then it would be useful to add that information

Resolving patch:
diff --git a/statsmodels/tsa/vector_ar/var_model.py b/statsmodels/tsa/vector_ar/var_model.py
--- a/statsmodels/tsa/vector_ar/var_model.py
+++ b/statsmodels/tsa/vector_ar/var_model.py
@@ -24,6 +24,7 @@
 from statsmodels.tools.decorators import cache_readonly, deprecated_alias
 from statsmodels.tools.linalg import logdet_symm
 from statsmodels.tools.sm_exceptions import OutputWarning
+from statsmodels.tools.validation import array_like
 from statsmodels.tsa.tsatools import vec, unvec, duplication_matrix
 from statsmodels.tsa.vector_ar import output, plotting, util
 from statsmodels.tsa.vector_ar.hypothesis_test_results import \
@@ -1030,6 +1031,15 @@ def forecast(self, y, steps, exog_future=None):
         if self.exog is not None and exog_future is None:
             raise ValueError("Please provide an exog_future argument to "
                              "the forecast method.")
+
+        exog_future = array_like(exog_future, "exog_future", optional=True, ndim=2)
+        if exog_future is not None:
+            if exog_future.shape[0] != steps:
+                err_msg = f"""\
+exog_future only has {exog_future.shape[0]} observations. It must have \
+steps ({steps}) observations.
+"""
+                raise ValueError(err_msg)
         trend_coefs = None if self.coefs_exog.size == 0 else self.coefs_exog.T
 
         exogs = []


Test patch:
diff --git a/statsmodels/tsa/vector_ar/tests/test_var.py b/statsmodels/tsa/vector_ar/tests/test_var.py
--- a/statsmodels/tsa/vector_ar/tests/test_var.py
+++ b/statsmodels/tsa/vector_ar/tests/test_var.py
@@ -783,6 +783,10 @@ def test_exog(self):
         exf = np.arange(len(data), len(data) + h)
         fc2 = res_lin_trend1.forecast(res_lin_trend1.endog[-2:], h,
                                       exog_future=exf)
+        with pytest.raises(ValueError, match="exog_future only has"):
+            wrong_exf = np.arange(len(data), len(data) + h // 2)
+            res_lin_trend1.forecast(res_lin_trend1.endog[-2:], h,
+                                    exog_future=wrong_exf)
         exf2 = exf[:, None]**[0, 1]
         fc3 = res_lin_trend2.forecast(res_lin_trend2.endog[-2:], h,
                                       exog_future=exf2)