'The low field\'s aggregation returns the smallest low seen between
the market open and the current dt.
If there has been no data on or before the `dt` the low is `nan`.
Returns
np.array with dtype=float64, in order of assets parameter.'

def lows(self, assets, dt):

    (market_open, prev_dt, dt_value, entries) = self._prelude(dt, 'low')
    lows = []
    session_label = self._trading_calendar.minute_to_session_label(dt)
    for asset in assets:
        if (not asset.is_alive_for_session(session_label)):
            lows.append(np.NaN)
            continue
        if (prev_dt is None):
            val = self._minute_reader.get_value(asset, dt, 'low')
            entries[asset] = (dt_value, val)
            lows.append(val)
            continue
        else:
            try:
                (last_visited_dt, last_min) = entries[asset]
                if (last_visited_dt == dt_value):
                    lows.append(last_min)
                    continue
                elif (last_visited_dt == prev_dt):
                    curr_val = self._minute_reader.get_value(asset, dt, 'low')
                    val = np.nanmin([last_min, curr_val])
                    entries[asset] = (dt_value, val)
                    lows.append(val)
                    continue
                else:
                    after_last = pd.Timestamp((last_visited_dt + self._one_min), tz='UTC')
                    window = self._minute_reader.load_raw_arrays(['low'], after_last, dt, [asset])[0].T
                    val = np.nanmin(np.append(window, last_min))
                    entries[asset] = (dt_value, val)
                    lows.append(val)
                    continue
            except KeyError:
                window = self._minute_reader.load_raw_arrays(['low'], market_open, dt, [asset])[0].T
                val = np.nanmin(window)
                entries[asset] = (dt_value, val)
                lows.append(val)
                continue
    return np.array(lows)
