Skip to content
All library documents

Calculating Simple, Logarithmic, and Cumulative Returns from Closing Prices

Code Technical Analysis

Summary

This module defines three return measures from a series of closing prices. Daily simple return is the percentage change from the previous close; daily logarithmic return is the difference between successive log prices; and cumulative return is the percentage change from the first close in the series. Each measure is returned as a named time series.

An optional missing-value setting is passed through a shared fill routine. When filling is enabled, the implementation uses zero for missing daily and log returns and a negative-one value for missing cumulative returns. The code presents formulas and implementation behavior, but no market example or evidence comparing the measures. In practice, interpretation depends on the data’s price conventions and how missing observations are handled; the initial observation also has no prior close for daily returns.

Key ideas

  • Simple daily return measures the percentage change from the previous closing price.
  • Log return is computed as the change in the natural logarithm of closing prices.
  • Cumulative return compares each close with the first close in the series.
  • Optional missing-value filling uses different defaults for daily and cumulative measures.
  • Daily return is undefined at the start of a series because there is no previous close.

Tags

Full text
# others.py


```py
"""
.. module:: others
   :synopsis: Others Indicators.

.. moduleauthor:: Dario Lopez Padial (Bukosabino)

"""
import numpy as np
import pandas as pd

from ta.utils import IndicatorMixin


class DailyReturnIndicator(IndicatorMixin):
    """Daily Return (DR)

    Args:
        close(pandas.Series): dataset 'Close' column.
        fillna(bool): if True, fill nan values.
    """

    def __init__(self, close: pd.Series, fillna: bool = False):
        self._close = close
        self._fillna = fillna
        self._run()

    def _run(self):
        self._dr = (self._close / self._close.shift(1)) - 1
        self._dr *= 100

    def daily_return(self) -> pd.Series:
        """Daily Return (DR)

        Returns:
            pandas.Series: New feature generated.
        """
        dr_series = self._check_fillna(self._dr, value=0)
        return pd.Series(dr_series, name="d_ret")


class DailyLogReturnIndicator(IndicatorMixin):
    """Daily Log Return (DLR)

    https://stackoverflow.com/questions/31287552/logarithmic-returns-in-pandas-dataframe

    Args:
        close(pandas.Series): dataset 'Close' column.
        fillna(bool): if True, fill nan values.
    """

    def __init__(self, close: pd.Series, fillna: bool = False):
        self._close = close
        self._fillna = fillna
        self._run()

    def _run(self):
        self._dr = pd.Series(np.log(self._close)).diff()
        self._dr *= 100

    def daily_log_return(self) -> pd.Series:
        """Daily Log Return (DLR)

        Returns:
            pandas.Series: New feature generated.
        """
        dr_series = self._check_fillna(self._dr, value=0)
        return pd.Series(dr_series, name="d_logret")


class CumulativeReturnIndicator(IndicatorMixin):
    """Cumulative Return (CR)

    Args:
        close(pandas.Series): dataset 'Close' column.
        fillna(bool): if True, fill nan values.
    """

    def __init__(self, close: pd.Series, fillna: bool = False):
        self._close = close
        self._fillna = fillna
        self._run()

    def _run(self):
        self._cr = (self._close / self._close.iloc[0]) - 1
        self._cr *= 100

    def cumulative_return(self) -> pd.Series:
        """Cumulative Return (CR)

        Returns:
            pandas.Series: New feature generated.
        """
        cum_ret = self._check_fillna(self._cr, value=-1)
        return pd.Series(cum_ret, name="cum_ret")


def daily_return(close, fillna=False):
    """Daily Return (DR)

    Args:
        close(pandas.Series): dataset 'Close' column.
        fillna(bool): if True, fill nan values.

    Returns:
        pandas.Series: New feature generated.
    """
    return DailyReturnIndicator(close=close, fillna=fillna).daily_return()


def daily_log_return(close, fillna=False):
    """Daily Log Return (DLR)

    https://stackoverflow.com/questions/31287552/logarithmic-returns-in-pandas-dataframe

    Args:
        close(pandas.Series): dataset 'Close' column.
        fillna(bool): if True, fill nan values.

    Returns:
        pandas.Series: New feature generated.
    """
    return DailyLogReturnIndicator(close=close, fillna=fillna).daily_log_return()


def cumulative_return(close, fillna=False):
    """Cumulative Return (CR)

    Args:
        close(pandas.Series): dataset 'Close' column.
        fillna(bool): if True, fill nan values.

    Returns:
        pandas.Series: New feature generated.
    """
    return CumulativeReturnIndicator(close=close, fillna=fillna).cumulative_return()

```

Shown in full with attribution under the source's licence. Licence: MIT

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.