diff --git a/toarstats/__init__.py b/toarstats/__init__.py
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ff6d5cb3e771bca6bf49d0cb1e6854a1282f7f62 100644
--- a/toarstats/__init__.py
+++ b/toarstats/__init__.py
@@ -0,0 +1,10 @@
+"""The toarstats package.
+
+This package contains the following two subpackages:
+metrics - calculate metrics on time series
+trends - calculate trends on time series
+"""
+
+from toarstats import metrics, trends
+
+__all__ = ["metrics", "trends"]
diff --git a/toarstats/trends/__init__.py b/toarstats/trends/__init__.py
index 47d89bc5a3a0996228936a541fbe0514a1033801..052d97791348c418f5a641c8dbd4e2be8d8949c6 100644
--- a/toarstats/trends/__init__.py
+++ b/toarstats/trends/__init__.py
@@ -1,4 +1,12 @@
 """The trends subpackage.
 
 This subpackage contains trend analysis tools for time series.
+
+This subpackage exports the following function:
+calculate_trend - public interface for the trends subpackage
 """
+
+from toarstats.trends.interface import calculate_trend
+
+
+__all__ = ["calculate_trend"]
diff --git a/toarstats/trends/interface.py b/toarstats/trends/interface.py
new file mode 100644
index 0000000000000000000000000000000000000000..f4ce6637549e9d0c46357000a36fd6a3cafc19a8
--- /dev/null
+++ b/toarstats/trends/interface.py
@@ -0,0 +1,46 @@
+"""This module contains the public interface for the trends subpackage.
+
+This module contains the following function:
+calculate_trend - calculate the trend using the requested method
+"""
+
+from toarstats.trends.ols import ols
+from toarstats.trends.quant_reg import quant_reg
+from toarstats.trends.utils import deseasonalize
+
+
+def calculate_trend(method, data, formula="value ~ datetime", quantiles=None):
+    """Calculate the trend using the requested method.
+
+    This function is the public interface for the ``trends`` subpackage.
+    It takes all the user inputs and returns the result of the requested
+    trend analysis.
+
+    :param method: either ``"OLS"`` or ``"quant"``
+    :param data: data containing a list of date time values and
+                 associated parameter values on which to calculate the
+                 trend
+    :param formula: the formula specifying the model
+    :param quantiles: a single quantile or a list of quantiles to
+                      calculate, these must be between 0 and 1; only
+                      needed when ``method="quant"``
+
+    :raises ValueError: raised if the ``method`` parameter is not
+                        recognized
+
+    :return: The result of the fit or a list of fit results if
+             ``method="quant"`` and multiple quantiles are given
+    """
+    deseasonalized_data = deseasonalize(data)
+    if method == "OLS":
+        fit = ols(deseasonalized_data, formula)
+    elif method == "quant":
+        try:
+            fit = [quant_reg(deseasonalized_data, formula, quantile)
+                   for quantile in quantiles]
+        except TypeError:
+            fit = quant_reg(deseasonalized_data, formula, quantiles)
+    else:
+        raise ValueError(f"{method} is not recognized, must be 'OLS' or"
+                         " 'quant'")
+    return fit
diff --git a/toarstats/trends/ols.py b/toarstats/trends/ols.py
new file mode 100644
index 0000000000000000000000000000000000000000..255741d5a974bd450a2b8be0bdbc5bca972981b7
--- /dev/null
+++ b/toarstats/trends/ols.py
@@ -0,0 +1,22 @@
+"""Ordinary least squares (OLS) linear regression calculation.
+
+This module contains the following function:
+ols - calculate the OLS linear regression
+"""
+
+import statsmodels.formula.api as smf
+
+
+def ols(data, formula):
+    """Calculate the OLS linear regression.
+
+    :param data: data containing a list of date time values and
+                 associated parameter values on which to calculate the
+                 trend
+    :param formula: the formula specifying the model
+
+    :return: The result of the fit
+    """
+    model = smf.ols(formula, data)
+    fit = model.fit()
+    return fit
diff --git a/toarstats/trends/quant_reg.py b/toarstats/trends/quant_reg.py
new file mode 100644
index 0000000000000000000000000000000000000000..033597761266c22a61ad45aeece6b1212e0d00d6
--- /dev/null
+++ b/toarstats/trends/quant_reg.py
@@ -0,0 +1,23 @@
+"""Quantile regression calculation.
+
+This module contains the following function:
+quant_reg - calculate the OLS linear regression
+"""
+
+import statsmodels.formula.api as smf
+
+
+def quant_reg(data, formula, quantile):
+    """Calculate the quantile regression.
+
+    :param data: data containing a list of date time values and
+                 associated parameter values on which to calculate the
+                 trend
+    :param formula: the formula specifying the model
+    :param quantile: a single quantile, must be between 0 and 1
+
+    :return: The result of the fit
+    """
+    model = smf.quantreg(formula, data)
+    fit = model.fit(q=quantile)
+    return fit
diff --git a/toarstats/trends/utils.py b/toarstats/trends/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..0a07989d0c6fadc1115b6c3c4d0407ecbe982d2d
--- /dev/null
+++ b/toarstats/trends/utils.py
@@ -0,0 +1,29 @@
+"""This module contains helper functions for the trends subpackage.
+
+This module contains the following function:
+deseasonalize - calculate the trend using the requested method
+"""
+
+import numpy as np
+import pandas as pd
+import statsmodels.formula.api as smf
+
+
+def deseasonalize(data):
+    """Deseasonalize the data.
+
+    :param data: data containing a list of date time values and
+                 associated parameter values
+
+    :return: The deseasonalized data
+    """
+    seasonal_cycle = smf.ols(
+        "value~np.cos(month*2*np.pi/12)+np.sin(month*2*np.pi/12)"
+        "+np.cos(month*4*np.pi/12)+np.sin(month*4*np.pi/12)",
+        pd.DataFrame({"value": data["value"], "month": data.index.month})
+    ).fit(method="qr").predict(pd.DataFrame({"month": range(1, 13)}))
+    idx = data.index
+    return pd.DataFrame({
+        "value": data["value"].values - seasonal_cycle[idx.month-1].values,
+        "datetime": (idx.year-2000)*12 + idx.month
+    })