Ejemplo n.º 1
0
    def test_preprocess_on_function(self, args, kwargs):

        decorators = [
            preprocess(a=call(str), b=call(float), c=call(lambda x: x + 1)),
        ]

        for decorator in decorators:
            @decorator
            def func(a, b, c=3):
                return a, b, c
            self.assertEqual(func(*args, **kwargs), ('1', 2.0, 4))
Ejemplo n.º 2
0
    def test_preprocess_on_function(self, args, kwargs):

        decorators = [
            preprocess(a=call(str), b=call(float), c=call(lambda x: x + 1)),
        ]

        for decorator in decorators:
            @decorator
            def func(a, b, c=3):
                return a, b, c
            self.assertEqual(func(*args, **kwargs), ('1', 2.0, 4))
Ejemplo n.º 3
0
def expect_dtypes(**named):
    """
    Preprocessing decorator that verifies inputs have expected numpy dtypes.

    Usage
    -----
    >>> from numpy import dtype, arange, int8, float64
    >>> @expect_dtypes(x=dtype(int8))
    ... def foo(x, y):
    ...    return x, y
    ...
    >>> foo(arange(3, dtype=int8), 'foo')
    (array([0, 1, 2], dtype=int8), 'foo')
    >>> foo(arange(3, dtype=float64), 'foo')  # doctest: +NORMALIZE_WHITESPACE
    ...                                       # doctest: +ELLIPSIS
    Traceback (most recent call last):
       ...
    TypeError: ...foo() expected a value with dtype 'int8' for argument 'x',
    but got 'float64' instead.
    """
    for name, type_ in iteritems(named):
        if not isinstance(type_, (dtype, tuple)):
            raise TypeError(
                "expect_dtypes() expected a numpy dtype or tuple of dtypes"
                " for argument {name!r}, but got {dtype} instead.".format(
                    name=name, dtype=dtype,
                )
            )

    @preprocess(dtypes=call(lambda x: x if isinstance(x, tuple) else (x,)))
    def _expect_dtype(dtypes):
        """
        Factory for dtype-checking functions that work with the @preprocess
        decorator.
        """
        def error_message(func, argname, value):
            # If the bad value has a dtype, but it's wrong, show the dtype
            # name.  Otherwise just show the value.
            try:
                value_to_show = value.dtype.name
            except AttributeError:
                value_to_show = value
            return (
                "{funcname}() expected a value with dtype {dtype_str} "
                "for argument {argname!r}, but got {value!r} instead."
            ).format(
                funcname=_qualified_name(func),
                dtype_str=' or '.join(repr(d.name) for d in dtypes),
                argname=argname,
                value=value_to_show,
            )

        def _actual_preprocessor(func, argname, argvalue):
            if getattr(argvalue, 'dtype', object()) not in dtypes:
                raise TypeError(error_message(func, argname, argvalue))
            return argvalue

        return _actual_preprocessor

    return preprocess(**valmap(_expect_dtype, named))
Ejemplo n.º 4
0
def expect_kinds(**named):
    """
    Preprocessing decorator that verifies inputs have expected dtype kinds.

    Usage
    -----
    >>> from numpy import int64, int32, float32
    >>> @expect_kinds(x='i')
    ... def foo(x):
    ...    return x
    ...
    >>> foo(int64(2))
    2
    >>> foo(int32(2))
    2
    >>> foo(float32(2))
    Traceback (most recent call last):
       ...n
    TypeError: foo() expected a numpy object of kind 'i' for argument 'x', but got 'f' instead.  # noqa
    """
    for name, kind in iteritems(named):
        if not isinstance(kind, (str, tuple)):
            raise TypeError(
                "expect_dtype_kinds() expected a string or tuple of strings"
                " for argument {name!r}, but got {kind} instead.".format(
                    name=name, kind=dtype,
                )
            )

    @preprocess(kinds=call(lambda x: x if isinstance(x, tuple) else (x,)))
    def _expect_kind(kinds):
        """
        Factory for kind-checking functions that work the @preprocess
        decorator.
        """
        def error_message(func, argname, value):
            # If the bad value has a dtype, but it's wrong, show the dtype
            # kind.  Otherwise just show the value.
            try:
                value_to_show = value.dtype.kind
            except AttributeError:
                value_to_show = value
            return (
                "{funcname}() expected a numpy object of kind {kinds} "
                "for argument {argname!r}, but got {value!r} instead."
            ).format(
                funcname=_qualified_name(func),
                kinds=' or '.join(map(repr, kinds)),
                argname=argname,
                value=value_to_show,
            )

        def _actual_preprocessor(func, argname, argvalue):
            if getattrs(argvalue, ('dtype', 'kind'), object()) not in kinds:
                raise TypeError(error_message(func, argname, argvalue))
            return argvalue

        return _actual_preprocessor

    return preprocess(**valmap(_expect_kind, named))
Ejemplo n.º 5
0
def expect_kinds(**named):
    """
    Preprocessing decorator that verifies inputs have expected dtype kinds.

    Usage
    -----
    >>> from numpy import int64, int32, float32
    >>> @expect_kinds(x='i')
    ... def foo(x):
    ...    return x
    ...
    >>> foo(int64(2))
    2
    >>> foo(int32(2))
    2
    >>> foo(float32(2))  # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
    Traceback (most recent call last):
       ...
    TypeError: ...foo() expected a numpy object of kind 'i' for argument 'x',
    but got 'f' instead.
    """
    for name, kind in iteritems(named):
        if not isinstance(kind, (str, tuple)):
            raise TypeError(
                "expect_dtype_kinds() expected a string or tuple of strings"
                " for argument {name!r}, but got {kind} instead.".format(
                    name=name,
                    kind=dtype,
                ))

    @preprocess(kinds=call(lambda x: x if isinstance(x, tuple) else (x, )))
    def _expect_kind(kinds):
        """
        Factory for kind-checking functions that work the @preprocess
        decorator.
        """
        def error_message(func, argname, value):
            # If the bad value has a dtype, but it's wrong, show the dtype
            # kind.  Otherwise just show the value.
            try:
                value_to_show = value.dtype.kind
            except AttributeError:
                value_to_show = value
            return (
                "{funcname}() expected a numpy object of kind {kinds} "
                "for argument {argname!r}, but got {value!r} instead.").format(
                    funcname=_qualified_name(func),
                    kinds=' or '.join(map(repr, kinds)),
                    argname=argname,
                    value=value_to_show,
                )

        def _actual_preprocessor(func, argname, argvalue):
            if getattrs(argvalue, ('dtype', 'kind'), object()) not in kinds:
                raise TypeError(error_message(func, argname, argvalue))
            return argvalue

        return _actual_preprocessor

    return preprocess(**valmap(_expect_kind, named))
Ejemplo n.º 6
0
def expect_dtypes(**named):
    """
    Preprocessing decorator that verifies inputs have expected numpy dtypes.

    Usage
    -----
    >>> from numpy import dtype, arange, int8, float64
    >>> @expect_dtypes(x=dtype(int8))
    ... def foo(x, y):
    ...    return x, y
    ...
    >>> foo(arange(3, dtype=int8), 'foo')
    (array([0, 1, 2], dtype=int8), 'foo')
    >>> foo(arange(3, dtype=float64), 'foo')  # doctest: +NORMALIZE_WHITESPACE
    ...                                       # doctest: +ELLIPSIS
    Traceback (most recent call last):
       ...
    TypeError: ...foo() expected a value with dtype 'int8' for argument 'x',
    but got 'float64' instead.
    """
    for name, type_ in iteritems(named):
        if not isinstance(type_, (dtype, tuple)):
            raise TypeError(
                "expect_dtypes() expected a numpy dtype or tuple of dtypes"
                " for argument {name!r}, but got {dtype} instead.".format(
                    name=name, dtype=dtype,
                )
            )

    @preprocess(dtypes=call(lambda x: x if isinstance(x, tuple) else (x,)))
    def _expect_dtype(dtypes):
        """
        Factory for dtype-checking functions that work with the @preprocess
        decorator.
        """
        def error_message(func, argname, value):
            # If the bad value has a dtype, but it's wrong, show the dtype
            # name.  Otherwise just show the value.
            try:
                value_to_show = value.dtype.name
            except AttributeError:
                value_to_show = value
            return (
                "{funcname}() expected a value with dtype {dtype_str} "
                "for argument {argname!r}, but got {value!r} instead."
            ).format(
                funcname=_qualified_name(func),
                dtype_str=' or '.join(repr(d.name) for d in dtypes),
                argname=argname,
                value=value_to_show,
            )

        def _actual_preprocessor(func, argname, argvalue):
            if getattr(argvalue, 'dtype', object()) not in dtypes:
                raise TypeError(error_message(func, argname, argvalue))
            return argvalue

        return _actual_preprocessor

    return preprocess(**valmap(_expect_dtype, named))
Ejemplo n.º 7
0
    def test_preprocess_on_method(self, args, kwargs):
        decorators = [preprocess(a=call(str), b=call(float), c=call(lambda x: x + 1))]

        for decorator in decorators:

            class Foo(object):
                @decorator
                def method(self, a, b, c=3):
                    return a, b, c

                @classmethod
                @decorator
                def clsmeth(cls, a, b, c=3):
                    return a, b, c

            self.assertEqual(Foo.clsmeth(*args, **kwargs), ("1", 2.0, 4))
            self.assertEqual(Foo().method(*args, **kwargs), ("1", 2.0, 4))
Ejemplo n.º 8
0
    def test_preprocess_on_method(self, args, kwargs):
        decorators = [
            preprocess(a=call(str), b=call(float), c=call(lambda x: x + 1)),
        ]

        for decorator in decorators:

            class Foo:
                @decorator
                def method(self, a, b, c=3):
                    return a, b, c

                @classmethod
                @decorator
                def clsmeth(cls, a, b, c=3):
                    return a, b, c

            self.assertEqual(Foo.clsmeth(*args, **kwargs), ('1', 2.0, 4))
            self.assertEqual(Foo().method(*args, **kwargs), ('1', 2.0, 4))
Ejemplo n.º 9
0
    def test_preprocess_on_method(self, args, kwargs):
        decorators = [
            preprocess(a=call(str), b=call(float), c=call(lambda x: x + 1)),
        ]

        for decorator in decorators:

            class Foo(object):
                @decorator
                def method(self, a, b, c=3):
                    return a, b, c

                @classmethod
                @decorator
                def clsmeth(cls, a, b, c=3):
                    return a, b, c

            assert Foo.clsmeth(*args, **kwargs) == ("1", 2.0, 4)
            assert Foo().method(*args, **kwargs) == ("1", 2.0, 4)
Ejemplo n.º 10
0
class PanelBarReader(SessionBarReader):
    """
    Reader for data passed as Panel.

    DataPanel Structure
    -------
    items : Int64Index
        Asset identifiers.  Must be unique.
    major_axis : DatetimeIndex
       Dates for data provided provided by the Panel.  Must be unique.
    minor_axis : ['open', 'high', 'low', 'close', 'volume']
       Price attributes.  Must be unique.

    Attributes
    ----------
    The table with which this loader interacts contains the following
    attributes:

    panel : pd.Panel
        The panel from which to read OHLCV data.
    first_trading_day : pd.Timestamp
        The first trading day in the dataset.
    """
    @preprocess(panel=call(verify_indices_all_unique))
    @expect_element(data_frequency={'daily', 'minute'})
    def __init__(self, trading_calendar, panel, data_frequency):

        panel = panel.copy()
        if 'volume' not in panel.minor_axis:
            # Fake volume if it does not exist.
            panel.loc[:, :, 'volume'] = int(1e9)

        self.trading_calendar = trading_calendar
        self._first_trading_day = trading_calendar.minute_to_session_label(
            panel.major_axis[0])
        last_trading_day = trading_calendar.minute_to_session_label(
            panel.major_axis[-1])

        self.sessions = trading_calendar.sessions_in_range(
            self.first_trading_day, last_trading_day)

        if data_frequency == 'daily':
            self._calendar = self.sessions
        elif data_frequency == 'minute':
            self._calendar = trading_calendar.minutes_for_sessions_in_range(
                self.first_trading_day, last_trading_day)

        self.panel = panel

    sessions = None

    @property
    def last_available_dt(self):
        return self._calendar[-1]

    trading_calendar = None

    def load_raw_arrays(self, columns, start_dt, end_dt, assets):
        cal = self._calendar
        return self.panel.loc[list(assets), start_dt:end_dt,
                              list(columns)].reindex(
                                  major_axis=cal[cal.slice_indexer(
                                      start_dt, end_dt)]).values.T

    def get_value(self, sid, dt, field):
        """
        Parameters
        ----------
        sid : int
            The asset identifier.
        day : datetime64-like
            Midnight of the day for which data is requested.
        field : string
            The price field. e.g. ('open', 'high', 'low', 'close', 'volume')

        Returns
        -------
        float
            The spot price for colname of the given sid on the given day.
            Raises a NoDataOnDate exception if the given day and sid is before
            or after the date range of the equity.
            Returns -1 if the day is within the date range, but the price is
            0.
        """
        return self.panel.loc[sid, dt, field]

    def get_last_traded_dt(self, asset, dt):
        """
        Parameters
        ----------
        asset : zipline.asset.Asset
            The asset identifier.
        dt : datetime64-like
            Midnight of the day for which data is requested.

        Returns
        -------
        pd.Timestamp : The last know dt for the asset and dt;
                       NaT if no trade is found before the given dt.
        """
        try:
            return self.panel.loc[int(asset), :dt, 'close'].last_valid_index()
        except IndexError:
            return NaT

    @property
    def first_trading_day(self):
        return self._first_trading_day
Ejemplo n.º 11
0
class PanelDailyBarReader(DailyBarReader):
    """
    Reader for data passed as Panel.

    DataPanel Structure
    -------
    items : Int64Index
        Asset identifiers.  Must be unique.
    major_axis : DatetimeIndex
       Dates for data provided provided by the Panel.  Must be unique.
    minor_axis : ['open', 'high', 'low', 'close', 'volume']
       Price attributes.  Must be unique.

    Attributes
    ----------
    The table with which this loader interacts contains the following
    attributes:

    panel : pd.Panel
        The panel from which to read OHLCV data.
    first_trading_day : pd.Timestamp
        The first trading day in the dataset.
    """
    @preprocess(panel=call(verify_indices_all_unique))
    def __init__(self, calendar, panel):

        panel = panel.copy()
        if 'volume' not in panel.minor_axis:
            # Fake volume if it does not exist.
            panel.loc[:, :, 'volume'] = int(1e9)

        self.first_trading_day = panel.major_axis[0]
        self._calendar = calendar

        self.panel = panel

    @property
    def last_available_dt(self):
        return self._calendar[-1]

    def load_raw_arrays(self, columns, start_date, end_date, assets):
        columns = list(columns)
        cal = self._calendar
        index = cal[cal.slice_indexer(start_date, end_date)]
        shape = (len(index), len(assets))
        results = []
        for col in columns:
            outbuf = zeros(shape=shape)
            for i, asset in enumerate(assets):
                data = self.panel.loc[asset, start_date:end_date, col]
                data = data.reindex_axis(index).values
                outbuf[:, i] = data
            results.append(outbuf)
        return results

    def spot_price(self, sid, day, colname):
        """
        Parameters
        ----------
        sid : int
            The asset identifier.
        day : datetime64-like
            Midnight of the day for which data is requested.
        colname : string
            The price field. e.g. ('open', 'high', 'low', 'close', 'volume')

        Returns
        -------
        float
            The spot price for colname of the given sid on the given day.
            Raises a NoDataOnDate exception if the given day and sid is before
            or after the date range of the equity.
            Returns -1 if the day is within the date range, but the price is
            0.
        """
        return self.panel.loc[sid, day, colname]

    def get_last_traded_dt(self, sid, dt):
        """
        Parameters
        ----------
        sid : int
            The asset identifier.
        dt : datetime64-like
            Midnight of the day for which data is requested.

        Returns
        -------
        pd.Timestamp : The last know dt for the asset and dt;
                       NaT if no trade is found before the given dt.
        """
        while dt in self.panel.major_axis:
            freq = self.panel.major_axis.freq
            if not isnull(self.panel.loc[sid, dt, 'close']):
                return dt
            dt -= freq
        else:
            return NaT