diff --git a/mlair/helpers/statistics.py b/mlair/helpers/statistics.py
index 69d58766f9d54727cfd8e057ce965e7054037d89..5af011db9133a22d3b7dbe30197ec16f60c7e5db 100644
--- a/mlair/helpers/statistics.py
+++ b/mlair/helpers/statistics.py
@@ -225,14 +225,28 @@ def index_of_agreement(a, b, dim=None):
     return 1 - frac
 
 
+def modified_normalized_mean_bias(a, b, dim=None):
+    """Calculate modified normalized mean bias (MNMB) where a is the forecast and b the reference (e.g. observation)."""
+    N = np.count_nonzero(a) if len(a.shape) == 1 else a.notnull().sum(dim)
+    return 2 * ((a - b) / (a + b)).sum(dim) / N
+
+
 def calculate_error_metrics(a, b, dim):
-    """Calculate MSE, RMSE, MAE, and IOA. Aditionally, return number of used values for calculation."""
+    """Calculate MSE, RMSE, MAE, IOA, and MNMB. Additionally, return number of used values for calculation.
+
+    :param a: forecast data to calculate metrics for
+    :param b: reference (e.g. observation)
+    :param dim: dimension to calculate metrics along
+
+    :returns: dict with results for all metrics indicated by lowercase metric short name
+    """
     mse = mean_squared_error(a, b, dim)
     rmse = np.sqrt(mse)
     mae = mean_absolute_error(a, b, dim)
     ioa = index_of_agreement(a, b, dim)
+    mnmb = modified_normalized_mean_bias(a, b, dim)
     n = (a - b).notnull().sum(dim)
-    return {"mse": mse, "rmse": rmse, "mae": mae, "ioa": ioa, "n": n}
+    return {"mse": mse, "rmse": rmse, "mae": mae, "ioa": ioa, "mnmb": mnmb, "n": n}
 
 
 def mann_whitney_u_test(data: pd.DataFrame, reference_col_name: str, **kwargs):
diff --git a/test/test_helpers/test_statistics.py b/test/test_helpers/test_statistics.py
index 06b77935cc06cdf0e2dfe5865e9e134f22095074..a12e6dcd5d47c15ee1bc2241ce4be1fa444eee1e 100644
--- a/test/test_helpers/test_statistics.py
+++ b/test/test_helpers/test_statistics.py
@@ -6,7 +6,7 @@ import xarray as xr
 from mlair.helpers.statistics import standardise, standardise_inverse, standardise_apply, centre, centre_inverse, \
     centre_apply, apply_inverse_transformation, min_max, min_max_inverse, min_max_apply, log, log_inverse, log_apply, \
     create_single_bootstrap_realization, calculate_average, create_n_bootstrap_realizations, mean_squared_error, \
-    mean_absolute_error, calculate_error_metrics, index_of_agreement
+    mean_absolute_error, calculate_error_metrics, index_of_agreement, modified_normalized_mean_bias
 from mlair.helpers.testing import check_nested_equality
 
 lazy = pytest.lazy_fixture
@@ -323,6 +323,41 @@ class TestIndexOfAgreement:
         assert xr.testing.assert_allclose(res, expected, atol=10**-2) is None
 
 
+class TestMNMB:
+
+    def test_modified_normalized_mean_bias(self):
+        d1 = np.array([1, 2, 3, 4, 5])
+        d2 = np.array([1, 2, 3, 4, 5])
+        assert modified_normalized_mean_bias(d1, d2) == 0
+        d1 = np.array([1, 2, 3, 4, 7])
+        assert np.testing.assert_almost_equal(modified_normalized_mean_bias(d1, d2), 0.0666, 3) is None
+        d1 = np.array([3, 4, 5, 6, 7])
+        assert np.testing.assert_almost_equal(modified_normalized_mean_bias(d1, d2), 0.58, 3) is None
+        assert np.testing.assert_almost_equal(modified_normalized_mean_bias(d2, d1), -0.58, 3) is None
+
+    def test_modified_normalized_mean_bias_xarray(self):
+        d1 = np.array([np.array([1, 2, 3, 4, 5]), np.array([1, 2, 3, 4, 5]), np.array([1, 2, 3, 4, 5])])
+        d2 = np.array([np.array([2, 4, 3, 4, 6]), np.array([2, 3, 3, 4, 5]), np.array([0, 1, 3, 4, 5])])
+        shape = d1.shape
+        coords = {'index': range(shape[0]), 'value': range(shape[1])}
+        x_array1 = xr.DataArray(d1, coords=coords, dims=coords.keys())
+        x_array2 = xr.DataArray(d2, coords=coords, dims=coords.keys())
+        expected = xr.DataArray(np.array([0, 0, 0]), coords={"index": [0, 1, 2]}, dims=["index"])
+        res = modified_normalized_mean_bias(x_array1, x_array1, dim="value")
+        assert xr.testing.assert_equal(res, expected) is None
+        expected = xr.DataArray(np.array([0, 0, 0, 0, 0]), coords={"value": [0, 1, 2, 3, 4]}, dims=["value"])
+        res = modified_normalized_mean_bias(x_array1, x_array1, dim="index")
+        assert xr.testing.assert_equal(res, expected) is None
+        expected = xr.DataArray(np.array([-0.3030, -0.2133, 0.5333]), coords={"index": [0, 1, 2]}, dims=["index"])
+        res = modified_normalized_mean_bias(x_array1, x_array2, dim="value")
+        assert xr.testing.assert_allclose(res, expected, atol=10**-2) is None
+        res = modified_normalized_mean_bias(x_array2, x_array1, dim="value")
+        assert xr.testing.assert_allclose(res, -expected, atol=10**-2) is None
+        expected = xr.DataArray(np.array([0.2222, -0.1333, 0, 0, -0.0606]), coords={"value": [0, 1, 2, 3, 4]}, dims=["value"])
+        res = modified_normalized_mean_bias(x_array1, x_array2, dim="index")
+        assert xr.testing.assert_allclose(res, expected, atol=10**-2) is None
+
+
 class TestCalculateErrorMetrics:
 
     def test_calculate_error_metrics(self):
@@ -336,6 +371,7 @@ class TestCalculateErrorMetrics:
                     "rmse": np.sqrt(xr.DataArray(np.array([1, 2, 0, 0, 1./3]), coords={"value": [0, 1, 2, 3, 4]}, dims=["value"])),
                     "mae": xr.DataArray(np.array([1, 4./3, 0, 0, 1./3]), coords={"value": [0, 1, 2, 3, 4]}, dims=["value"]),
                     "ioa": xr.DataArray(np.array([0.3721, 0.4255, 1, 1, 0.4706]), coords={"value": [0, 1, 2, 3, 4]}, dims=["value"]),
+                    "mnmb": xr.DataArray(np.array([0.2222, -0.1333, 0, 0, -0.0606]), coords={"value": [0, 1, 2, 3, 4]}, dims=["value"]),
                     "n": xr.DataArray(np.array([3, 3, 3, 3, 3]), coords={"value": [0, 1, 2, 3, 4]}, dims=["value"])}
         assert check_nested_equality(expected, calculate_error_metrics(x_array1, x_array2, "index"), 3) is True
 
@@ -343,5 +379,6 @@ class TestCalculateErrorMetrics:
                     "rmse": np.sqrt(xr.DataArray(np.array([1.2, 0.4, 0.4]), coords={"index": [0, 1, 2]}, dims=["index"])),
                     "mae": xr.DataArray(np.array([0.8, 0.4, 0.4]), coords={"index": [0, 1, 2]}, dims=["index"]),
                     "ioa": xr.DataArray(np.array([0.8478, 0.9333, 0.9629]), coords={"index": [0, 1, 2]}, dims=["index"]),
+                    "mnmb": xr.DataArray(np.array([-0.3030, -0.2133, 0.5333]), coords={"index": [0, 1, 2]}, dims=["index"]),
                     "n": xr.DataArray(np.array([5, 5, 5]), coords={"index": [0, 1, 2]}, dims=["index"])}
         assert check_nested_equality(expected, calculate_error_metrics(x_array1, x_array2, "value"), 3) is True