def apply_adjustment(df, adj_date, adj_value,
                    adj_type='mul',date_col='date',
                    cols=['open','high', 'low', 'close']):
    """
    Apply adjustment to a given stock
    df
        dataframe of the given stock
    adj_date
        date from which the adjustment is
        to be made
    adj_value
        value to be adjusted
    adj_type
        method of adjustment **mul/sub**
        mul means multiply all the values
            such as splits and bonuses
        sub means subtract the values
            such as dividends
 
    date_col
        date column  on which the adjustment
        is to be applied
    cols
        columns to which the adjustment is to
        be made

    Notes
    -----
    1) You can use negative values to add to the
    stock value by using **adj_type=sub**
    2) Adjustment is applied prior to all dates
    in the dataframe
    3) In case your dataframe has date or
    symbol as indexes, reset them
    """
    df = df.set_index(date_col).sort_index()
    values_on_adj_date = df.loc[adj_date, cols].copy()
    if adj_type == "mul":
        adjusted_values = (df.loc[:adj_date, cols] * adj_value).round(2)
    elif adj_type == "sub":
        adjusted_values = (df.loc[:adj_date, cols] - adj_value).round(2)
    else:
        raise ValueError('adj_type should be either mul or sub')
    df.loc[:adj_date, cols] = adjusted_values
    df.loc[adj_date, cols] = values_on_adj_date
    return df.reset_index()