def calcEMA(df, period_len, col="close"):
    """
    Calculates Exponential Moving Average (EMA)
    Read about EMA: https://www.investopedia.com/terms/e/ema.asp

    Args:
        df : pandas.DataFrame()
            dataframe of historical ticker data
        period_len : int
            length of moving average periods
        col: str
            which col to use for calculation
    Returns:
        pandas.DataFrame()
            dataframe of calculated EMA of period_len + original data
    """
    prev_ema = None

    if col == "MACD":
        ma = df[col].head(26 + period_len).mean()

        def __calc(row):
            nonlocal prev_ema
            if period_len + 26 >= row.name + 1:
                return None
            elif prev_ema != None:
                ema_today = (row[col] * ((2 / (period_len + 1)))) + (
                    prev_ema * (1 - (2 / (period_len + 1)))
                )
                prev_ema = ema_today
                return ema_today
            else:
                ema_today = (row[col] * ((2 / (period_len + 1)))) + (
                    ma * (1 - (2 / (period_len + 1)))
                )
                prev_ema = ema_today
                return ema_today

    else:
        ma = df[col].head(period_len).mean()

        def __calc(row):
            nonlocal prev_ema
            if period_len >= row.name + 1:
                return None
            elif prev_ema != None:
                ema_today = (row[col] * ((2 / (period_len + 1)))) + (
                    prev_ema * (1 - (2 / (period_len + 1)))
                )
                prev_ema = ema_today
                return ema_today
            else:
                ema_today = (row[col] * ((2 / (period_len + 1)))) + (
                    ma * (1 - (2 / (period_len + 1)))
                )
                prev_ema = ema_today
                return ema_today

    copy_df = df.copy().reset_index()
    arr = copy_df.apply(__calc, axis=1).values
    return arr