コード例 #1
0
ファイル: assets.py プロジェクト: moreorless/zipline
    def lookup_future_by_expiration(self, root_symbol, as_of_date, ref_date):
        """ Find a specific contract in the futures chain by expiration
        date.

        Parameters
        ----------
        root_symbol : str
            Root symbol of the desired future.
        as_of_date : pd.Timestamp
            Date at the time of the lookup.
        ref_date : pd.Timestamp
            Reference point for expiration dates.

        Returns
        -------
        Future
            The valid contract the has the closest expiration date
            after ref_date. If none exists, returns None.
        """
        root_symbol.upper()
        as_of_date = normalize_date(as_of_date)
        ref_date = normalize_date(ref_date)

        valid_contracts = self._valid_contracts(root_symbol, as_of_date)

        contracts_after_date = (c for c in valid_contracts
                                if c.expiration_date > ref_date)
        return next(contracts_after_date, None)
コード例 #2
0
ファイル: resample.py プロジェクト: dragoljub/pandas
def _get_range_edges(axis, offset, closed='left', base=0):
    if isinstance(offset, basestring):
        offset = to_offset(offset)

    if isinstance(offset, Tick):
        day_nanos = _delta_to_nanoseconds(timedelta(1))
        # #1165
        if (day_nanos % offset.nanos) == 0:
            return _adjust_dates_anchored(axis[0], axis[-1], offset,
                                          closed=closed, base=base)

    first, last = axis[0], axis[-1]
    if not isinstance(offset, Tick):  # and first.time() != last.time():
        # hack!
        first = tools.normalize_date(first)
        last = tools.normalize_date(last)

    if closed == 'left':
        first = Timestamp(offset.rollback(first))
    else:
        first = Timestamp(first - offset)

    last = Timestamp(last + offset)

    return first, last
コード例 #3
0
ファイル: resample.py プロジェクト: CarstVaartjes/pandas
def _get_range_edges(first, last, offset, closed='left', base=0):
    if isinstance(offset, compat.string_types):
        offset = to_offset(offset)

    if isinstance(offset, Tick):
        is_day = isinstance(offset, Day)
        day_nanos = _delta_to_nanoseconds(timedelta(1))

        # #1165
        if (is_day and day_nanos % offset.nanos == 0) or not is_day:
            return _adjust_dates_anchored(first, last, offset,
                                          closed=closed, base=base)

    if not isinstance(offset, Tick):  # and first.time() != last.time():
        # hack!
        first = tools.normalize_date(first)
        last = tools.normalize_date(last)

    if closed == 'left':
        first = Timestamp(offset.rollback(first))
    else:
        first = Timestamp(first - offset)

    last = Timestamp(last + offset)

    return first, last
コード例 #4
0
ファイル: test_util.py プロジェクト: 8ballbb/ProjectRothar
def test_normalize_date():
    value = date(2012, 9, 7)

    result = normalize_date(value)
    assert (result == datetime(2012, 9, 7))

    value = datetime(2012, 9, 7, 12)

    result = normalize_date(value)
    assert (result == datetime(2012, 9, 7))
コード例 #5
0
ファイル: index.py プロジェクト: candre717/pandas
    def _generate(cls, start, end, periods, name, offset,
                  tz=None, normalize=False):
        _normalized = True

        if start is not None:
            start = Timestamp(start)
            if not isinstance(start, Timestamp):
                raise ValueError('Failed to convert %s to timestamp'
                                 % start)

            if normalize:
                start = normalize_date(start)
                _normalized = True
            else:
                _normalized = _normalized and start.time() == _midnight

        if end is not None:
            end = Timestamp(end)
            if not isinstance(end, Timestamp):
                raise ValueError('Failed to convert %s to timestamp'
                                 % end)

            if normalize:
                end = normalize_date(end)
                _normalized = True
            else:
                _normalized = _normalized and end.time() == _midnight

        start, end, tz = tools._figure_out_timezone(start, end, tz)

        if (offset._should_cache() and
            not (offset._normalize_cache and not _normalized) and
            _naive_in_cache_range(start, end)):
            index = cls._cached_range(start, end, periods=periods,
                                      offset=offset, name=name)
        else:
            index = _generate_regular_range(start, end, periods, offset)

        if tz is not None:
            # Convert local to UTC
            ints = index.view('i8')
            lib.tz_localize_check(ints, tz)
            index = lib.tz_convert(ints, tz, _utc())
            index = index.view('M8[us]')

        index = index.view(cls)
        index.name = name
        index.offset = offset
        index.tz = tz

        return index
コード例 #6
0
ファイル: assets.py プロジェクト: AshBT/zipline
    def lookup_symbol_resolve_multiple(self, symbol, as_of_date=None):
        """
        Return matching Asset of name symbol in database.

        If multiple Assets are found and as_of_date is not set,
        raises MultipleSymbolsFound.

        If no Asset was active at as_of_date, and allow_expired is False
        raises SymbolNotFound.
        """
        if as_of_date is not None:
            as_of_date = normalize_date(as_of_date)

        if symbol not in self.sym_cache:
            raise SymbolNotFound(symbol=symbol)

        infos = self.sym_cache[symbol]
        if as_of_date is None:
            if len(infos) == 1:
                return infos[0]
            else:
                raise MultipleSymbolsFound(symbol=symbol,
                                           options=str(infos))

        # Try to find symbol matching as_of_date
        asset, _ = self._lookup_symbol_in_infos(infos, as_of_date)
        if asset is None:
            raise SymbolNotFound(symbol=symbol)
        return asset
コード例 #7
0
ファイル: protocol.py プロジェクト: runtBlue/zipline
 def factors(self):
     algo = get_algo_instance()
     today = normalize_date(algo.get_datetime())
     if today > self._factor_matrix_expires:
         self._factor_matrix, self._factor_matrix_expires = \
             algo.compute_factor_matrix(today)
     return self._factor_matrix.loc[today]
コード例 #8
0
ファイル: assets.py プロジェクト: moreorless/zipline
    def lookup_future_in_chain(self, root_symbol, as_of_date, contract_num=0):
        """ Find a specific contract in the futures chain for a given
        root symbol.

        Parameters
        ----------
        root_symbol : str
            Root symbol of the desired future.
        as_of_date : pd.Timestamp
            Date at the time of the lookup.
        contract_num : int
            1 for the primary contract, 2 for the secondary, etc.,
            relative to as_of_date.

        Returns
        -------
        Future
            The (contract_num)th contract in the futures chain. If none
            exits, returns None.
        """
        root_symbol.upper()
        as_of_date = normalize_date(as_of_date)

        valid_contracts = self._valid_contracts(root_symbol, as_of_date)

        if valid_contracts and contract_num >= 0:
            try:
                return valid_contracts[contract_num]
            except IndexError:
                pass

        return None
コード例 #9
0
ファイル: tracker.py プロジェクト: ABDieng/zipline
    def handle_minute_close(self, dt, data_portal):
        """
        Handles the close of the given minute in minute emission.

        Parameters
        __________
        dt : Timestamp
            The minute that is ending

        Returns
        _______
        A minute perf packet.
        """
        self.position_tracker.sync_last_sale_prices(dt, False, data_portal)
        self.update_performance()
        todays_date = normalize_date(dt)
        account = self.get_account(False)

        bench_returns = self.all_benchmark_returns.loc[todays_date:dt]
        # cumulative returns
        bench_since_open = (1. + bench_returns).prod() - 1

        self.cumulative_risk_metrics.update(todays_date,
                                            self.todays_performance.returns,
                                            bench_since_open,
                                            account.leverage)

        minute_packet = self.to_dict(emission_type='minute')
        return minute_packet
コード例 #10
0
ファイル: tracker.py プロジェクト: Jfeng3/zipline
    def handle_minute_close(self, dt):
        todays_date = normalize_date(dt)

        minute_returns = self.minute_performance.returns
        self.minute_performance.rollover()
        # the intraday risk is calculated on top of minute performance
        # returns for the bench and the algo
        self.intraday_risk_metrics.update(dt,
                                          minute_returns,
                                          self.all_benchmark_returns[dt])

        bench_since_open = \
            self.intraday_risk_metrics.benchmark_period_returns[dt]

        # if we've reached market close, check on dividends
        if dt == self.market_close:
            for perf_period in self.perf_periods:
                perf_period.update_dividends(todays_date)

        self.cumulative_risk_metrics.update(todays_date,
                                            self.todays_performance.returns,
                                            bench_since_open)

        # if this is the close, save the returns objects for cumulative
        # risk calculations
        if dt == self.market_close:
            self.returns[todays_date] = self.todays_performance.returns
コード例 #11
0
ファイル: cumulative.py プロジェクト: JayStar/zipline
    def __init__(self, sim_params, returns_frequency=None, create_first_day_stats=False):
        """
        - @returns_frequency allows for configuration of the whether
        the benchmark and algorithm returns are in units of minutes or days,
        if `None` defaults to the `emission_rate` in `sim_params`.
        """

        self.treasury_curves = trading.environment.treasury_curves
        self.start_date = sim_params.period_start.replace(hour=0, minute=0, second=0, microsecond=0)
        self.end_date = sim_params.period_end.replace(hour=0, minute=0, second=0, microsecond=0)

        self.trading_days = trading.environment.days_in_range(self.start_date, self.end_date)

        last_day = normalize_date(sim_params.period_end)
        if last_day not in self.trading_days:
            last_day = pd.tseries.index.DatetimeIndex([last_day])
            self.trading_days = self.trading_days.append(last_day)

        self.sim_params = sim_params

        self.create_first_day_stats = create_first_day_stats

        if returns_frequency is None:
            returns_frequency = self.sim_params.emission_rate

        self.returns_frequency = returns_frequency

        if returns_frequency == "daily":
            cont_index = self.get_daily_index()
        elif returns_frequency == "minute":
            cont_index = self.get_minute_index(sim_params)

        self.cont_index = cont_index

        self.algorithm_returns_cont = pd.Series(index=cont_index)
        self.benchmark_returns_cont = pd.Series(index=cont_index)

        # The returns at a given time are read and reset from the respective
        # returns container.
        self.algorithm_returns = None
        self.benchmark_returns = None
        self.mean_returns = None
        self.annualized_mean_returns = None
        self.mean_benchmark_returns = None
        self.annualized_benchmark_returns = None

        self.algorithm_cumulative_returns = pd.Series(index=cont_index)
        self.benchmark_cumulative_returns = pd.Series(index=cont_index)
        self.excess_returns = pd.Series(index=cont_index)

        self.latest_dt = cont_index[0]

        self.metrics = pd.DataFrame(index=cont_index, columns=self.METRIC_NAMES)

        self.drawdowns = pd.Series(index=cont_index)
        self.max_drawdowns = pd.Series(index=cont_index)
        self.max_drawdown = 0
        self.current_max = -np.inf
        self.daily_treasury = pd.Series(index=self.trading_days)
コード例 #12
0
ファイル: index.py プロジェクト: MikeLindenau/pandas
    def _generate(cls, start, end, periods, name, offset,
                  tz=None, normalize=False):
        _normalized = True

        if start is not None:
            start = Timestamp(start)
            if normalize:
                start = normalize_date(start)
                _normalized = True
            else:
                _normalized = _normalized and start.time() == _midnight

        if end is not None:
            end = Timestamp(end)

            if normalize:
                end = normalize_date(end)
                _normalized = True
            else:
                _normalized = _normalized and end.time() == _midnight

        start, end, tz = tools._figure_out_timezone(start, end, tz)

        if com._count_not_none(start, end, periods) < 2:
            raise ValueError('Must specify two of start, end, or periods')

        if (offset._should_cache() and
            not (offset._normalize_cache and not _normalized) and
            _naive_in_cache_range(start, end)):
            index = cls._cached_range(start, end, periods=periods,
                                      offset=offset, name=name)
        else:
            index = _generate_regular_range(start, end, periods, offset)

        if tz is not None:
            # Convert local to UTC
            ints = index.view('i8', type=np.ndarray)
            index = lib.tz_localize_to_utc(ints, tz)
            index = index.view(_NS_DTYPE)

        index = index.view(cls)
        index.name = name
        index.offset = offset
        index.tz = tz

        return index
コード例 #13
0
ファイル: futures.py プロジェクト: rongyuhuang/zipline
    def _get_datetime(self):
        """
        Returns the normalized simulation datetime.

        Returns
        -------
        pandas.Timestamp
            The normalized datetime of FutureChain's TradingAlgorithm.
        """
        return normalize_date(Timestamp(self._algorithm_get_datetime(), tz="UTC"))
コード例 #14
0
ファイル: assets.py プロジェクト: robertotang/zipline
    def __init__(self,
                 metadata=None,
                 allow_sid_assignment=True,
                 fuzzy_char=None,
                 db_path=':memory:',
                 create_table=True):

        self.fuzzy_char = fuzzy_char

        # This flag controls if the AssetFinder is allowed to generate its own
        # sids. If False, metadata that does not contain a sid will raise an
        # exception when building assets.
        self.allow_sid_assignment = allow_sid_assignment

        if allow_sid_assignment:
            self.end_date_to_assign = normalize_date(
                pd.Timestamp('now', tz='UTC'))

        self.conn = sqlite3.connect(db_path)
        self.conn.text_factory = str
        self.cursor = self.conn.cursor()

        # The AssetFinder also holds a nested-dict of all metadata for
        # reference when building Assets
        self.metadata_cache = {}

        # Create table and read in metadata.
        # Should we use flags like 'r', 'w', instead?
        # What we need to support is:
        # - A 'throwaway' mode where the metadata is read each run.
        # - A 'write' mode where the data is written to the provided db_path
        # - A 'read' mode where the asset finder uses a prexisting db.
        if create_table:
            self.create_db_tables()
            if metadata is not None:
                self.consume_metadata(metadata)

        # Cache for lookup of assets by sid, the objects in the asset lookp may
        # be shared with the results from equity and future lookup caches.
        #
        # The top level cache exists to minimize lookups on the asset type
        # routing.
        #
        # The caches are read through, i.e. accessing an asset through
        # retrieve_asset, _retrieve_equity etc. will populate the cache on
        # first retrieval.
        self._asset_cache = {}
        self._equity_cache = {}
        self._future_cache = {}

        self._asset_type_cache = {}

        # Populated on first call to `lifetimes`.
        self._asset_lifetimes = None
コード例 #15
0
ファイル: resample.py プロジェクト: dragoljub/pandas
def _adjust_dates_anchored(first, last, offset, closed='right', base=0):
    from pandas.tseries.tools import normalize_date

    start_day_nanos = Timestamp(normalize_date(first)).value
    last_day_nanos = Timestamp(normalize_date(last)).value

    base_nanos = (base % offset.n) * offset.nanos // offset.n
    start_day_nanos += base_nanos
    last_day_nanos += base_nanos

    foffset = (first.value - start_day_nanos) % offset.nanos
    loffset = (last.value - last_day_nanos) % offset.nanos

    if closed == 'right':
        if foffset > 0:
            # roll back
            fresult = first.value - foffset
        else:
            fresult = first.value - offset.nanos

        if loffset > 0:
            # roll forward
            lresult = last.value + (offset.nanos - loffset)
        else:
            # already the end of the road
            lresult = last.value
    else:  # closed == 'left'
        if foffset > 0:
            fresult = first.value - foffset
        else:
            # start of the road
            fresult = first.value

        if loffset > 0:
            # roll forward
            lresult = last.value + (offset.nanos - loffset)
        else:
            lresult = last.value + offset.nanos

    return (Timestamp(fresult, tz=first.tz),
            Timestamp(lresult, tz=last.tz))
コード例 #16
0
ファイル: assets.py プロジェクト: chrjxj/zipline
    def lookup_symbol(self, symbol, as_of_date, fuzzy=False):
        """
        If a fuzzy string is provided, then we try various symbols based on
        the provided symbol.  This is to facilitate mapping from a broker's
        symbol to ours in cases where mapping to the broker's symbol loses
        information. For example, if we have CMCS_A, but a broker has CMCSA,
        when the broker provides CMCSA, it can also provide fuzzy='_',
        so we can find a match by inserting an underscore.
        """

        symbol = symbol.upper()
        ad_value = pd.Timestamp(normalize_date(as_of_date)).value

        if not fuzzy:
            try:
                return self.lookup_symbol_resolve_multiple(symbol, as_of_date)
            except SymbolNotFound:
                return None

        fuzzy = symbol.replace(self.fuzzy_char, "")

        equities_cols = self.equities.c
        candidates = (
            sa.select((equities_cols.sid,))
            .where(
                (equities_cols.fuzzy == fuzzy)
                & (equities_cols.start_date <= ad_value)
                & (equities_cols.end_date >= ad_value)
            )
            .execute()
            .fetchall()
        )

        # If one SID exists for symbol, return that symbol
        if len(candidates) == 1:
            return self._retrieve_equity(candidates[0]["sid"])

        # If multiple SIDs exist for symbol, return latest start_date with
        # end_date as a tie-breaker
        elif candidates:
            sid = (
                sa.select((equities_cols.sid,))
                .where((equities_cols.symbol == symbol) & (equities_cols.start_date <= ad_value))
                .order_by(equities_cols.start_date.desc(), equities_cols.end_date.desc())
                .scalar()
            )
            if sid:
                return self._retrieve_equity(sid)

        raise SymbolNotFound(symbol=symbol)
コード例 #17
0
ファイル: protocol.py プロジェクト: NJ32/zipline
 def factors(self):
     algo = get_algo_instance()
     today = normalize_date(algo.get_datetime())
     if today > self._factor_matrix_expires:
         self._factor_matrix, self._factor_matrix_expires = \
             algo.compute_factor_matrix(today)
     try:
         return self._factor_matrix.loc[today]
     except KeyError:
         # This happens if no assets passed our filters on a given day.
         return pd.DataFrame(
             index=[],
             columns=self._factor_matrix.columns,
         )
コード例 #18
0
ファイル: easter.py プロジェクト: WarnWang/Dissertation
    def wrapper(self, other):
        if other is tslib.NaT:
            return tslib.NaT
        elif isinstance(other, (timedelta, Tick, DateOffset)):
            # timedelta path
            return func(self, other)
        elif isinstance(other, (np.datetime64, datetime, date)):
            other = as_timestamp(other)

        tz = getattr(other, 'tzinfo', None)
        nano = getattr(other, 'nanosecond', 0)

        try:
            if self._adjust_dst and isinstance(other, Timestamp):
                other = other.tz_localize(None)

            result = func(self, other)
            if self._adjust_dst:
                result = tslib._localize_pydatetime(result, tz)

            result = Timestamp(result)
            if self.normalize:
                result = result.normalize()

            # nanosecond may be deleted depending on offset process
            if not self.normalize and nano != 0:
                if not isinstance(self, Nano) and result.nanosecond != nano:
                    if result.tz is not None:
                        # convert to UTC
                        value = tslib.tz_convert_single(
                            result.value, 'UTC', result.tz)
                    else:
                        value = result.value
                    result = Timestamp(value + nano)

            if tz is not None and result.tzinfo is None:
                result = tslib._localize_pydatetime(result, tz)

        except OutOfBoundsDatetime:
            result = func(self, as_datetime(other))

            if self.normalize:
                # normalize_date returns normal datetime
                result = normalize_date(result)

            if tz is not None and result.tzinfo is None:
                result = tslib._localize_pydatetime(result, tz)

        return result
コード例 #19
0
ファイル: tracker.py プロジェクト: Coinalytics/zipline
    def handle_market_close(self):
        self.update_performance()
        # add the return results from today to the returns series
        todays_date = normalize_date(self.market_close)
        self.cumulative_performance.update_dividends(todays_date)
        self.todays_performance.update_dividends(todays_date)

        self.returns[todays_date] = self.todays_performance.returns

        # update risk metrics for cumulative performance
        self.cumulative_risk_metrics.update(
            todays_date,
            self.todays_performance.returns,
            self.all_benchmark_returns[todays_date])

        # increment the day counter before we move markers forward.
        self.day_count += 1.0

        # Take a snapshot of our current performance to return to the
        # browser.
        daily_update = self.to_dict()

        # On the last day of the test, don't create tomorrow's performance
        # period.  We may not be able to find the next trading day if we're
        # at the end of our historical data
        if self.market_close >= self.last_close:
            return daily_update

        # move the market day markers forward
        self.market_open, self.market_close = \
            trading.environment.next_open_and_close(self.market_open)

        # Roll over positions to current day.
        self.todays_performance.rollover()
        self.todays_performance.period_open = self.market_open
        self.todays_performance.period_close = self.market_close

        # The dividend calculation for the daily needs to be made
        # after the rollover. midnight_between is the last midnight
        # hour between the close of markets and the next open. To
        # make sure midnight_between matches identically with
        # dividend data dates, it is in UTC.
        midnight_between = self.market_open.replace(hour=0, minute=0, second=0,
                                                    microsecond=0)
        self.cumulative_performance.update_dividends(midnight_between)
        self.todays_performance.update_dividends(midnight_between)

        return daily_update
コード例 #20
0
ファイル: assets.py プロジェクト: moreorless/zipline
    def lookup_future_chain(self, root_symbol, as_of_date):
        """ Return the futures chain for a given root symbol.

        Parameters
        ----------
        root_symbol : str
            Root symbol of the desired future.
        as_of_date : pd.Timestamp
            Date at the time of the lookup.

        Returns
        -------
        [Future]
        """
        root_symbol.upper()
        as_of_date = normalize_date(as_of_date)
        return self._valid_contracts(root_symbol, as_of_date)
コード例 #21
0
ファイル: test_assets.py プロジェクト: ngdanielsimeon/zipline
    def test_sid_assignment(self):

        # This metadata does not contain SIDs
        metadata = ["PLAY", "MSFT"]

        today = normalize_date(pd.Timestamp("2015-07-09", tz="UTC"))

        # Write data with sid assignment
        self.env.write_data(equities_identifiers=metadata, allow_sid_assignment=True)

        # Verify that Assets were built and different sids were assigned
        finder = AssetFinder(self.env.engine)
        play = finder.lookup_symbol("PLAY", today)
        msft = finder.lookup_symbol("MSFT", today)
        self.assertEqual("PLAY", play.symbol)
        self.assertIsNotNone(play.sid)
        self.assertNotEqual(play.sid, msft.sid)
コード例 #22
0
ファイル: assets.py プロジェクト: robertotang/zipline
    def lookup_symbol(self, symbol, as_of_date, fuzzy=False):
        """
        If a fuzzy string is provided, then we try various symbols based on
        the provided symbol.  This is to facilitate mapping from a broker's
        symbol to ours in cases where mapping to the broker's symbol loses
        information. For example, if we have CMCS_A, but a broker has CMCSA,
        when the broker provides CMCSA, it can also provide fuzzy='_',
        so we can find a match by inserting an underscore.
        """
        symbol = symbol.upper()
        as_of_date = normalize_date(as_of_date)

        if not fuzzy:
            try:
                return self.lookup_symbol_resolve_multiple(symbol, as_of_date)
            except SymbolNotFound:
                return None
        else:
            c = self.conn.cursor()
            fuzzy = symbol.replace(self.fuzzy_char, '')
            t = (fuzzy, as_of_date.value, as_of_date.value)
            query = ("select sid from equities "
                     "where fuzzy=? " +
                     "and start_date<=? " +
                     "and end_date>=?")
            c.execute(query, t)
            candidates = c.fetchall()

            # If one SID exists for symbol, return that symbol
            if len(candidates) == 1:
                return self._retrieve_equity(candidates[0][0])

            # If multiple SIDs exist for symbol, return latest start_date with
            # end_date as a tie-breaker
            if len(candidates) > 1:
                t = (symbol, as_of_date.value)
                query = ("select sid from equities "
                         "where symbol=? " +
                         "and start_date<=? " +
                         "order by start_date desc, end_date desc" +
                         "limit 1")
                c.execute(query, t)
                data = c.fetchone()
                if data:
                    return self._retrieve_equity(data[0])
コード例 #23
0
ファイル: resample.py プロジェクト: FedericoCeratto/pandas
def _adjust_dates_anchored(first, last, offset, closed='right', base=0):
    from pandas.tseries.tools import normalize_date

    # First and last offsets should be calculated from the start day to fix an
    # error cause by resampling across multiple days when a one day period is
    # not a multiple of the frequency.
    #
    # See https://github.com/pydata/pandas/issues/8683

    start_day_nanos = Timestamp(normalize_date(first)).value

    base_nanos = (base % offset.n) * offset.nanos // offset.n
    start_day_nanos += base_nanos

    foffset = (first.value - start_day_nanos) % offset.nanos
    loffset = (last.value - start_day_nanos) % offset.nanos

    if closed == 'right':
        if foffset > 0:
            # roll back
            fresult = first.value - foffset
        else:
            fresult = first.value - offset.nanos

        if loffset > 0:
            # roll forward
            lresult = last.value + (offset.nanos - loffset)
        else:
            # already the end of the road
            lresult = last.value
    else:  # closed == 'left'
        if foffset > 0:
            fresult = first.value - foffset
        else:
            # start of the road
            fresult = first.value

        if loffset > 0:
            # roll forward
            lresult = last.value + (offset.nanos - loffset)
        else:
            lresult = last.value + offset.nanos

    return (Timestamp(fresult, tz=first.tz),
            Timestamp(lresult, tz=last.tz))
コード例 #24
0
ファイル: test_assets.py プロジェクト: ronalcc/zipline
    def test_sid_assignment(self):

        # This metadata does not contain SIDs
        metadata = {'PLAY': {'symbol': 'PLAY'},
                    'MSFT': {'symbol': 'MSFT'}}

        today = normalize_date(pd.Timestamp('2015-07-09', tz='UTC'))

        # Build a finder that is allowed to assign sids
        finder = AssetFinder(metadata=metadata,
                             allow_sid_assignment=True)

        # Verify that Assets were built and different sids were assigned
        play = finder.lookup_symbol('PLAY', today)
        msft = finder.lookup_symbol('MSFT', today)
        self.assertEqual('PLAY', play.symbol)
        self.assertIsNotNone(play.sid)
        self.assertNotEqual(play.sid, msft.sid)
コード例 #25
0
ファイル: test_assets.py プロジェクト: maartenb/zipline
    def test_sid_assignment(self):

        # This metadata does not contain SIDs
        metadata = ['PLAY', 'MSFT']

        today = normalize_date(pd.Timestamp('2015-07-09', tz='UTC'))

        # Write data with sid assignment
        self.env.write_data(equities_identifiers=metadata,
                            allow_sid_assignment=True)

        # Verify that Assets were built and different sids were assigned
        finder = self.asset_finder_type(self.env.engine)
        play = finder.lookup_symbol('PLAY', today)
        msft = finder.lookup_symbol('MSFT', today)
        self.assertEqual('PLAY', play.symbol)
        self.assertIsNotNone(play.sid)
        self.assertNotEqual(play.sid, msft.sid)
コード例 #26
0
        def handle_data(context, data):
            today = normalize_date(get_datetime())
            results = pipeline_output("test")
            expect_over_300 = {AAPL: today < self.AAPL_split_date, MSFT: False, BRK_A: True}
            for asset in assets:
                should_pass_filter = expect_over_300[asset]
                if set_screen and not should_pass_filter:
                    self.assertNotIn(asset, results.index)
                    continue

                asset_results = results.loc[asset]
                self.assertEqual(asset_results["filter"], should_pass_filter)
                for length in vwaps:
                    computed = results.loc[asset, vwap_key(length)]
                    expected = vwaps[length][asset].loc[today]
                    # Only having two places of precision here is a bit
                    # unfortunate.
                    assert_almost_equal(computed, expected, decimal=2)
コード例 #27
0
ファイル: tracker.py プロジェクト: chiragmatkar/zipline
    def handle_market_close_daily(self):
        """
        Function called after handle_data when running with daily emission
        rate.
        """
        self.update_performance()
        completed_date = normalize_date(self.market_close)
        account = self.get_account(True)

        # update risk metrics for cumulative performance
        self.cumulative_risk_metrics.update(
            completed_date,
            self.todays_performance.returns,
            self.all_benchmark_returns[completed_date],
            account)

        # increment the day counter before we move markers forward.
        self.day_count += 1.0

        # Take a snapshot of our current performance to return to the
        # browser.
        daily_update = self.to_dict()

        # On the last day of the test, don't create tomorrow's performance
        # period.  We may not be able to find the next trading day if we're at
        # the end of our historical data
        if self.market_close >= self.last_close:
            return daily_update

        # move the market day markers forward
        self.market_open, self.market_close = \
            trading.environment.next_open_and_close(self.market_open)

        # Roll over positions to current day.
        self.todays_performance.rollover()
        self.todays_performance.period_open = self.market_open
        self.todays_performance.period_close = self.market_close

        self.check_upcoming_dividends(completed_date)

        self.account_needs_update = True

        return daily_update
コード例 #28
0
ファイル: tracker.py プロジェクト: eackermann/zipline
    def handle_minute_close(self, dt):
        self.update_performance()
        todays_date = normalize_date(dt)
        account = self.get_account(False)

        self.minute_performance.rollover()

        bench_returns = self.all_benchmark_returns.loc[todays_date:dt]
        # cumulative returns
        bench_since_open = (1. + bench_returns).prod() - 1

        self.cumulative_risk_metrics.update(todays_date,
                                            self.todays_performance.returns,
                                            bench_since_open,
                                            account)

        # if this is the close, update dividends for the next day.
        if dt == self.market_close:
            self.check_upcoming_dividends(todays_date)
コード例 #29
0
ファイル: tracker.py プロジェクト: AdaoSmith/zipline
    def handle_minute_close(self, dt, data_portal):
        """
        Handles the close of the given minute. This includes handling
        market-close functions if the given minute is the end of the market
        day.

        Parameters
        __________
        dt : Timestamp
            The minute that is ending

        Returns
        _______
        (dict, dict/None)
            A tuple of the minute perf packet and daily perf packet.
            If the market day has not ended, the daily perf packet is None.
        """
        self.position_tracker.sync_last_sale_prices(dt, False, data_portal)
        self.update_performance()
        todays_date = normalize_date(dt)
        account = self.get_account(False)

        bench_returns = self.all_benchmark_returns.loc[todays_date:dt]
        # cumulative returns
        bench_since_open = (1. + bench_returns).prod() - 1

        self.cumulative_risk_metrics.update(todays_date,
                                            self.todays_performance.returns,
                                            bench_since_open,
                                            account.leverage)

        minute_packet = self.to_dict(emission_type='minute')

        # if this is the close, update dividends for the next day.
        # Return the performance tuple
        if dt == self.market_close:
            return minute_packet, self._handle_market_close(
                todays_date, data_portal._adjustment_reader,
            )
        else:
            return minute_packet, None
コード例 #30
0
ファイル: assets.py プロジェクト: AshBT/zipline
    def lookup_symbol(self, symbol, as_of_date, fuzzy=None):
        """
        If a fuzzy string is provided, then we try various symbols based on
        the provided symbol.  This is to facilitate mapping from a broker's
        symbol to ours in cases where mapping to the broker's symbol loses
        information. For example, if we have CMCS_A, but a broker has CMCSA,
        when the broker provides CMCSA, it can also provide fuzzy='_',
        so we can find a match by inserting an underscore.
        """
        symbol = symbol.upper()
        as_of_date = normalize_date(as_of_date)

        if not fuzzy:
            try:
                return self.lookup_symbol_resolve_multiple(symbol, as_of_date)
            except SymbolNotFound:
                return None
        else:
            try:
                return self.fuzzy_match[(symbol, fuzzy, as_of_date)]
            except KeyError:
                # if symbol is CMCSA and fuzzy is '_', then
                # try CMCSA, then CMCS_A, then CMC_SA, etc.
                for fuzzy_symbol in chain(
                        (symbol,),
                        (symbol[:i] + fuzzy + symbol[i:]
                         for i in range(len(symbol) - 1, 0, -1))):

                    infos = self.sym_cache.get(fuzzy_symbol)
                    if infos:
                        info, date_match = self._lookup_symbol_in_infos(
                            infos,
                            as_of_date,
                        )

                        if info is not None and date_match:
                            self.fuzzy_match[(symbol, fuzzy, as_of_date)] = \
                                info
                            return info
                else:
                    self.fuzzy_match[(symbol, fuzzy, as_of_date)] = None
コード例 #31
0
    def __init__(self, sim_params):

        self.sim_params = sim_params

        self.period_start = self.sim_params.period_start
        self.period_end = self.sim_params.period_end
        self.last_close = self.sim_params.last_close
        first_day = self.sim_params.first_open
        self.market_open, self.market_close = \
            trading.environment.get_open_and_close(first_day)
        self.total_days = self.sim_params.days_in_period
        self.capital_base = self.sim_params.capital_base
        self.emission_rate = sim_params.emission_rate

        all_trading_days = trading.environment.trading_days
        mask = ((all_trading_days >= normalize_date(self.period_start)) &
                (all_trading_days <= normalize_date(self.period_end)))

        self.trading_days = all_trading_days[mask]

        self.perf_periods = []

        if self.emission_rate == 'daily':
            self.all_benchmark_returns = pd.Series(
                index=self.trading_days)
            self.intraday_risk_metrics = None
            self.cumulative_risk_metrics = \
                risk.RiskMetricsCumulative(self.sim_params)

        elif self.emission_rate == 'minute':
            self.all_benchmark_returns = pd.Series(index=pd.date_range(
                self.sim_params.first_open, self.sim_params.last_close,
                freq='Min'))
            self.intraday_risk_metrics = \
                risk.RiskMetricsCumulative(self.sim_params)

            self.cumulative_risk_metrics = \
                risk.RiskMetricsCumulative(self.sim_params,
                                           returns_frequency='daily',
                                           create_first_day_stats=True)

            self.minute_performance = PerformancePeriod(
                # initial cash is your capital base.
                self.capital_base,
                # the cumulative period will be calculated over the
                # entire test.
                self.period_start,
                self.period_end,
                # don't save the transactions for the cumulative
                # period
                keep_transactions=False,
                keep_orders=False,
                # don't serialize positions for cumualtive period
                serialize_positions=False
            )
            self.perf_periods.append(self.minute_performance)

        # this performance period will span the entire simulation from
        # inception.
        self.cumulative_performance = PerformancePeriod(
            # initial cash is your capital base.
            self.capital_base,
            # the cumulative period will be calculated over the entire test.
            self.period_start,
            self.period_end,
            # don't save the transactions for the cumulative
            # period
            keep_transactions=False,
            keep_orders=False,
            # don't serialize positions for cumualtive period
            serialize_positions=False
        )
        self.perf_periods.append(self.cumulative_performance)

        # this performance period will span just the current market day
        self.todays_performance = PerformancePeriod(
            # initial cash is your capital base.
            self.capital_base,
            # the daily period will be calculated for the market day
            self.market_open,
            self.market_close,
            keep_transactions=True,
            keep_orders=True,
            serialize_positions=True
        )
        self.perf_periods.append(self.todays_performance)

        self.saved_dt = self.period_start
        self.returns = pd.Series(index=self.trading_days)
        # one indexed so that we reach 100%
        self.day_count = 0.0
        self.txn_count = 0
        self.event_count = 0
コード例 #32
0
    def test_history_in_bts_volume_days(self, data_freq):
        """
        Test calling history() in before_trading_start()
        with daily volume bars.
        """
        algo_text = """
from zipline.api import history

def initialize(context):
    context.first_bts_call = True

def before_trading_start(context, data):
    if not context.first_bts_call:
        volume_bts = history(bar_count=2, frequency='1d', field='volume')
        context.volume_bts = volume_bts
    context.first_bts_call = False

def handle_data(context, data):
    volume_hd = history(bar_count=2, frequency='1d', field='volume')
    context.volume_hd = volume_hd
""".strip()

        #      March 2006
        # Su Mo Tu We Th Fr Sa
        #          1  2  3  4
        #  5  6  7  8  9 10 11
        # 12 13 14 15 16 17 18
        # 19 20 21 22 23 24 25
        # 26 27 28 29 30 31
        start = pd.Timestamp('2006-03-20', tz='UTC')
        end = pd.Timestamp('2006-03-22', tz='UTC')

        sim_params = factory.create_simulation_parameters(
            start=start, end=end, data_frequency=data_freq)

        test_algo = TradingAlgorithm(
            script=algo_text,
            data_frequency=data_freq,
            sim_params=sim_params,
            env=TestHistoryAlgo.env,
        )

        source = RandomWalkSource(start=start, end=end, freq=data_freq)
        output = test_algo.run(source)
        self.assertIsNotNone(output)

        # Get the volume recorded by history() within handle_data()
        volume_hd_0 = test_algo.volume_hd[0]
        volume_hd_1 = test_algo.volume_hd[1]
        # Get the volume recorded by history() within BTS
        volume_bts_0 = test_algo.volume_bts[0]
        volume_bts_1 = test_algo.volume_bts[1]

        penultimate_hd_dt = pd.Timestamp(
            '2006-03-21 4:00 PM', tz='US/Eastern').tz_convert('UTC')
        # Midnight of the day on which BTS is invoked.
        newest_bts_dt = normalize_date(pd.Timestamp(
            '2006-03-22 04:00 PM', tz='US/Eastern').tz_convert('UTC'))

        if data_freq == 'daily':
            # If we're dealing with daily data, then we record
            # canonicalized timestamps, so make conversion here:
            penultimate_hd_dt = normalize_date(penultimate_hd_dt)

        # When history() is called in BTS, its 'current' volume value
        # should equal the sum of the previous day.
        self.assertEquals(volume_hd_0[penultimate_hd_dt],
                          volume_bts_0[newest_bts_dt])
        self.assertEquals(volume_hd_1[penultimate_hd_dt],
                          volume_bts_1[newest_bts_dt])
コード例 #33
0
    def __init__(self, sim_params):

        self.sim_params = sim_params
        env = TradingEnvironment.instance()

        self.period_start = self.sim_params.period_start
        self.period_end = self.sim_params.period_end
        self.last_close = self.sim_params.last_close
        first_open = self.sim_params.first_open.tz_convert(env.exchange_tz)
        self.day = pd.Timestamp(datetime(first_open.year, first_open.month,
                                         first_open.day),
                                tz='UTC')
        self.market_open, self.market_close = env.get_open_and_close(self.day)
        self.total_days = self.sim_params.days_in_period
        self.capital_base = self.sim_params.capital_base
        self.emission_rate = sim_params.emission_rate

        all_trading_days = env.trading_days
        mask = ((all_trading_days >= normalize_date(self.period_start)) &
                (all_trading_days <= normalize_date(self.period_end)))

        self.trading_days = all_trading_days[mask]

        self.dividend_frame = pd.DataFrame()
        self._dividend_count = 0

        self.position_tracker = PositionTracker()

        self.perf_periods = []

        if self.emission_rate == 'daily':
            self.all_benchmark_returns = pd.Series(index=self.trading_days)
            self.cumulative_risk_metrics = \
                risk.RiskMetricsCumulative(self.sim_params)

        elif self.emission_rate == 'minute':
            self.all_benchmark_returns = pd.Series(
                index=pd.date_range(self.sim_params.first_open,
                                    self.sim_params.last_close,
                                    freq='Min'))

            self.cumulative_risk_metrics = \
                risk.RiskMetricsCumulative(self.sim_params,
                                           returns_frequency='daily',
                                           create_first_day_stats=True)

            self.minute_performance = PerformancePeriod(
                # initial cash is your capital base.
                self.capital_base,
                # the cumulative period will be calculated over the
                # entire test.
                self.period_start,
                self.period_end,
                # don't save the transactions for the cumulative
                # period
                keep_transactions=False,
                keep_orders=False,
                # don't serialize positions for cumualtive period
                serialize_positions=False)
            self.minute_performance.position_tracker = self.position_tracker
            self.perf_periods.append(self.minute_performance)

        # this performance period will span the entire simulation from
        # inception.
        self.cumulative_performance = PerformancePeriod(
            # initial cash is your capital base.
            self.capital_base,
            # the cumulative period will be calculated over the entire test.
            self.period_start,
            self.period_end,
            # don't save the transactions for the cumulative
            # period
            keep_transactions=False,
            keep_orders=False,
            # don't serialize positions for cumualtive period
            serialize_positions=False,
        )
        self.cumulative_performance.position_tracker = self.position_tracker
        self.perf_periods.append(self.cumulative_performance)

        # this performance period will span just the current market day
        self.todays_performance = PerformancePeriod(
            # initial cash is your capital base.
            self.capital_base,
            # the daily period will be calculated for the market day
            self.market_open,
            self.market_close,
            keep_transactions=True,
            keep_orders=True,
            serialize_positions=True,
        )
        self.todays_performance.position_tracker = self.position_tracker

        self.perf_periods.append(self.todays_performance)

        self.saved_dt = self.period_start
        # one indexed so that we reach 100%
        self.day_count = 0.0
        self.txn_count = 0

        self.account_needs_update = True
        self._account = None
コード例 #34
0
    def __init__(self, sim_params,
                 returns_frequency=None,
                 create_first_day_stats=False,
                 account=None):
        """
        - @returns_frequency allows for configuration of the whether
        the benchmark and algorithm returns are in units of minutes or days,
        if `None` defaults to the `emission_rate` in `sim_params`.
        """

        self.treasury_curves = trading.environment.treasury_curves
        self.start_date = sim_params.period_start.replace(
            hour=0, minute=0, second=0, microsecond=0
        )
        self.end_date = sim_params.period_end.replace(
            hour=0, minute=0, second=0, microsecond=0
        )

        self.trading_days = trading.environment.days_in_range(
            self.start_date,
            self.end_date)

        # Hold on to the trading day before the start,
        # used for index of the zero return value when forcing returns
        # on the first day.
        self.day_before_start = self.start_date - \
            trading.environment.trading_days.freq

        last_day = normalize_date(sim_params.period_end)
        if last_day not in self.trading_days:
            last_day = pd.tseries.index.DatetimeIndex(
                [last_day]
            )
            self.trading_days = self.trading_days.append(last_day)

        self.sim_params = sim_params

        self.create_first_day_stats = create_first_day_stats

        if returns_frequency is None:
            returns_frequency = self.sim_params.emission_rate

        self.returns_frequency = returns_frequency

        if returns_frequency == 'daily':
            cont_index = self.get_daily_index()
        elif returns_frequency == 'minute':
            cont_index = self.get_minute_index(sim_params)

        self.cont_index = cont_index
        self.cont_len = len(self.cont_index)

        empty_cont = np.full(self.cont_len, np.nan)

        self.algorithm_returns_cont = empty_cont.copy()
        self.benchmark_returns_cont = empty_cont.copy()
        self.algorithm_cumulative_leverages_cont = empty_cont.copy()
        self.mean_returns_cont = empty_cont.copy()
        self.annualized_mean_returns_cont = empty_cont.copy()
        self.mean_benchmark_returns_cont = empty_cont.copy()
        self.annualized_mean_benchmark_returns_cont = empty_cont.copy()

        # The returns at a given time are read and reset from the respective
        # returns container.
        self.algorithm_returns = None
        self.benchmark_returns = None
        self.mean_returns = None
        self.annualized_mean_returns = None
        self.mean_benchmark_returns = None
        self.annualized_mean_benchmark_returns = None

        self.algorithm_cumulative_returns = empty_cont.copy()
        self.benchmark_cumulative_returns = empty_cont.copy()
        self.algorithm_cumulative_leverages = empty_cont.copy()
        self.excess_returns = empty_cont.copy()

        self.latest_dt_loc = 0
        self.latest_dt = cont_index[0]

        self.metrics = pd.DataFrame(index=cont_index,
                                    columns=self.METRIC_NAMES,
                                    dtype=float)

        self.drawdowns = empty_cont.copy()
        self.max_drawdowns = empty_cont.copy()
        self.max_drawdown = 0
        self.max_leverages = empty_cont.copy()
        self.max_leverage = 0
        self.current_max = -np.inf
        self.daily_treasury = pd.Series(index=self.trading_days)
        self.treasury_period_return = np.nan

        self.num_trading_days = 0
コード例 #35
0
ファイル: assets.py プロジェクト: mirizzi/zipline
    def lookup_symbol(self, symbol, as_of_date, fuzzy=False):
        """
        Return matching Equity of name symbol in database.

        If multiple Equities are found and as_of_date is not set,
        raises MultipleSymbolsFound.

        If no Equity was active at as_of_date raises SymbolNotFound.
        """

        # Format inputs
        if as_of_date is not None:
            as_of_date = pd.Timestamp(normalize_date(as_of_date))

        company_symbol, share_class_symbol, fuzzy_symbol = \
            split_delimited_symbol(symbol)

        equities_cols = self.equities.c
        if as_of_date:
            ad_value = as_of_date.value

            if fuzzy:
                # Search for a single exact match on the fuzzy column
                fuzzy_candidates = sa.select((equities_cols.sid, )).where(
                    (equities_cols.fuzzy_symbol == fuzzy_symbol) &
                    (equities_cols.start_date <= ad_value) &
                    (equities_cols.end_date >=
                     ad_value), ).execute().fetchall()

                # If exactly one SID exists for fuzzy_symbol, return that sid
                if len(fuzzy_candidates) == 1:
                    return self._retrieve_equity(fuzzy_candidates[0]['sid'])

            # Search for exact matches of the split-up company_symbol and
            # share_class_symbol
            candidates = sa.select((equities_cols.sid, )).where(
                (equities_cols.company_symbol == company_symbol) &
                (equities_cols.share_class_symbol == share_class_symbol) &
                (equities_cols.start_date <= ad_value) &
                (equities_cols.end_date >= ad_value), ).execute().fetchall()

            # If exactly one SID exists for symbol, return that symbol
            if len(candidates) == 1:
                return self._retrieve_equity(candidates[0]['sid'])

            # If no SID exists for symbol, return SID with the
            # highest-but-not-over end_date
            elif not candidates:
                sid = sa.select((equities_cols.sid, )).where(
                    (equities_cols.company_symbol == company_symbol) &
                    (equities_cols.share_class_symbol == share_class_symbol) &
                    (equities_cols.start_date <= ad_value), ).order_by(
                        equities_cols.end_date.desc(), ).scalar()
                if sid is not None:
                    return self._retrieve_equity(sid)

            # If multiple SIDs exist for symbol, return latest start_date with
            # end_date as a tie-breaker
            elif len(candidates) > 1:
                sid = sa.select((equities_cols.sid, )).where(
                    (equities_cols.company_symbol == company_symbol) &
                    (equities_cols.share_class_symbol == share_class_symbol) &
                    (equities_cols.start_date <= ad_value), ).order_by(
                        equities_cols.start_date.desc(),
                        equities_cols.end_date.desc(),
                    ).scalar()
                if sid is not None:
                    return self._retrieve_equity(sid)

            raise SymbolNotFound(symbol=symbol)

        else:
            # If this is a fuzzy look-up, check if there is exactly one match
            # for the fuzzy symbol
            if fuzzy:
                fuzzy_sids = sa.select((equities_cols.sid, )).where(
                    (equities_cols.fuzzy_symbol == fuzzy_symbol
                     )).execute().fetchall()
                if len(fuzzy_sids) == 1:
                    return self._retrieve_equity(fuzzy_sids[0]['sid'])

            sids = sa.select((equities_cols.sid, )).where(
                (equities_cols.company_symbol == company_symbol)
                & (equities_cols.share_class_symbol == share_class_symbol)
            ).execute().fetchall()
            if len(sids) == 1:
                return self._retrieve_equity(sids[0]['sid'])
            elif not sids:
                raise SymbolNotFound(symbol=symbol)
            else:
                raise MultipleSymbolsFound(symbol=symbol,
                                           options=list(
                                               map(
                                                   compose(
                                                       self._retrieve_equity,
                                                       itemgetter('sid')),
                                                   sids,
                                               )))
コード例 #36
0
ファイル: cumulative.py プロジェクト: cosmicz/AlephNull
    def __init__(self,
                 sim_params,
                 returns_frequency=None,
                 create_first_day_stats=False):
        """
        - @returns_frequency allows for configuration of the whether
        the benchmark and algorithm returns are in units of minutes or days,
        if `None` defaults to the `emission_rate` in `sim_params`.
        """

        self.treasury_curves = trading.environment.treasury_curves
        self.start_date = sim_params.period_start.replace(hour=0,
                                                          minute=0,
                                                          second=0,
                                                          microsecond=0)
        self.end_date = sim_params.period_end.replace(hour=0,
                                                      minute=0,
                                                      second=0,
                                                      microsecond=0)

        self.trading_days = trading.environment.days_in_range(
            self.start_date, self.end_date)

        last_day = normalize_date(sim_params.period_end)
        if last_day not in self.trading_days:
            last_day = pd.tseries.index.DatetimeIndex([last_day])
            self.trading_days = self.trading_days.append(last_day)

        self.sim_params = sim_params

        self.create_first_day_stats = create_first_day_stats

        if returns_frequency is None:
            returns_frequency = self.sim_params.emission_rate

        self.returns_frequency = returns_frequency

        if returns_frequency == 'daily':
            cont_index = self.get_daily_index()
        elif returns_frequency == 'minute':
            cont_index = self.get_minute_index(sim_params)

        self.cont_index = cont_index

        self.algorithm_returns_cont = pd.Series(index=cont_index)
        self.benchmark_returns_cont = pd.Series(index=cont_index)

        # The returns at a given time are read and reset from the respective
        # returns container.
        self.algorithm_returns = None
        self.benchmark_returns = None
        self.mean_returns = None
        self.annualized_mean_returns = None
        self.mean_benchmark_returns = None
        self.annualized_benchmark_returns = None

        self.compounded_log_returns = pd.Series(index=cont_index)
        self.algorithm_period_returns = pd.Series(index=cont_index)
        self.benchmark_period_returns = pd.Series(index=cont_index)
        self.excess_returns = pd.Series(index=cont_index)

        self.latest_dt = cont_index[0]

        self.metrics = pd.DataFrame(index=cont_index,
                                    columns=self.METRIC_NAMES)

        self.max_drawdown = 0
        self.current_max = -np.inf
        self.daily_treasury = pd.Series(index=self.trading_days)
コード例 #37
0
ファイル: tracker.py プロジェクト: superzgc/zipline
    def __init__(self, sim_params, env, data_portal):
        self.sim_params = sim_params
        self.env = env

        self.period_start = self.sim_params.period_start
        self.period_end = self.sim_params.period_end
        self.last_close = self.sim_params.last_close
        first_open = self.sim_params.first_open.tz_convert(
            self.env.exchange_tz)
        self.day = pd.Timestamp(datetime(first_open.year, first_open.month,
                                         first_open.day),
                                tz='UTC')
        self.market_open, self.market_close = env.get_open_and_close(self.day)
        self.total_days = self.sim_params.days_in_period
        self.capital_base = self.sim_params.capital_base
        self.emission_rate = sim_params.emission_rate

        all_trading_days = env.trading_days
        mask = ((all_trading_days >= normalize_date(self.period_start)) &
                (all_trading_days <= normalize_date(self.period_end)))

        self.trading_days = all_trading_days[mask]

        self._data_portal = data_portal
        if data_portal is not None:
            self._adjustment_reader = data_portal._adjustment_reader
        else:
            self._adjustment_reader = None

        self.position_tracker = PositionTracker(
            asset_finder=env.asset_finder,
            data_portal=data_portal,
            data_frequency=self.sim_params.data_frequency)

        if self.emission_rate == 'daily':
            self.all_benchmark_returns = pd.Series(index=self.trading_days)
            self.cumulative_risk_metrics = \
                risk.RiskMetricsCumulative(self.sim_params, self.env)
        elif self.emission_rate == 'minute':
            self.all_benchmark_returns = pd.Series(
                index=pd.date_range(self.sim_params.first_open,
                                    self.sim_params.last_close,
                                    freq='Min'))

            self.cumulative_risk_metrics = \
                risk.RiskMetricsCumulative(self.sim_params, self.env,
                                           create_first_day_stats=True)

        # this performance period will span the entire simulation from
        # inception.
        self.cumulative_performance = PerformancePeriod(
            # initial cash is your capital base.
            starting_cash=self.capital_base,
            data_frequency=self.sim_params.data_frequency,
            data_portal=data_portal,
            # the cumulative period will be calculated over the entire test.
            period_open=self.period_start,
            period_close=self.period_end,
            # don't save the transactions for the cumulative
            # period
            keep_transactions=False,
            keep_orders=False,
            # don't serialize positions for cumulative period
            serialize_positions=False,
            asset_finder=self.env.asset_finder,
            name="Cumulative")
        self.cumulative_performance.position_tracker = self.position_tracker

        # this performance period will span just the current market day
        self.todays_performance = PerformancePeriod(
            # initial cash is your capital base.
            starting_cash=self.capital_base,
            data_frequency=self.sim_params.data_frequency,
            data_portal=data_portal,
            # the daily period will be calculated for the market day
            period_open=self.market_open,
            period_close=self.market_close,
            keep_transactions=True,
            keep_orders=True,
            serialize_positions=True,
            asset_finder=self.env.asset_finder,
            name="Daily")
        self.todays_performance.position_tracker = self.position_tracker

        self.saved_dt = self.period_start
        # one indexed so that we reach 100%
        self.day_count = 0.0
        self.txn_count = 0

        self.account_needs_update = True
        self._account = None
コード例 #38
0
    def test_history_in_bts_price_days(self, data_freq):
        """
        Test calling history() in before_trading_start()
        with daily price bars.
        """
        algo_text = """
from zipline.api import history

def initialize(context):
    context.first_bts_call = True

def before_trading_start(context, data):
    if not context.first_bts_call:
        prices_bts = history(bar_count=3, frequency='1d', field='price')
        context.prices_bts = prices_bts
    context.first_bts_call = False

def handle_data(context, data):
    prices_hd = history(bar_count=3, frequency='1d', field='price')
    context.prices_hd = prices_hd
""".strip()

        #      March 2006
        # Su Mo Tu We Th Fr Sa
        #          1  2  3  4
        #  5  6  7  8  9 10 11
        # 12 13 14 15 16 17 18
        # 19 20 21 22 23 24 25
        # 26 27 28 29 30 31
        start = pd.Timestamp('2006-03-20', tz='UTC')
        end = pd.Timestamp('2006-03-22', tz='UTC')

        sim_params = factory.create_simulation_parameters(
            start=start, end=end, data_frequency=data_freq)

        test_algo = TradingAlgorithm(
            script=algo_text,
            data_frequency=data_freq,
            sim_params=sim_params,
            env=TestHistoryAlgo.env,
        )

        source = RandomWalkSource(start=start, end=end, freq=data_freq)
        output = test_algo.run(source)
        self.assertIsNotNone(output)

        # Get the prices recorded by history() within handle_data()
        prices_hd = test_algo.prices_hd[0]
        # Get the prices recorded by history() within BTS
        prices_bts = test_algo.prices_bts[0]

        # before_trading_start() is timestamp'd to midnight prior to
        # the day's trading. Since no equity trades occur at midnight,
        # the price recorded for this time is forward filled from the
        # last trade - typically ~4pm the previous day. This results
        # in the OHLCV data recorded by history() in BTS lagging
        # that recorded by history in handle_data().
        # The trace of the pricing data from history() called within
        # handle_data() vs. BTS in the above algo is as follows:

        #  When called within handle_data()
        # ---------------------------------
        # 2006-03-20 21:00:00    139.369469
        # 2006-03-21 21:00:00    180.156620
        # 2006-03-22 21:00:00    221.344654

        #       When called within BTS
        # ---------------------------------
        # 2006-03-17 21:00:00           NaN
        # 2006-03-20 21:00:00    139.369469
        # 2006-03-22 00:00:00    180.156620

        # Get relevant Timestamps for the history() call within handle_data()
        oldest_hd_dt = pd.Timestamp(
            '2006-03-20 4:00 PM', tz='US/Eastern').tz_convert('UTC')
        penultimate_hd_dt = pd.Timestamp(
            '2006-03-21 4:00 PM', tz='US/Eastern').tz_convert('UTC')

        # Get relevant Timestamps for the history() call within BTS
        penultimate_bts_dt = pd.Timestamp(
            '2006-03-20 4:00 PM', tz='US/Eastern').tz_convert('UTC')
        newest_bts_dt = normalize_date(pd.Timestamp(
            '2006-03-22 04:00 PM', tz='US/Eastern').tz_convert('UTC'))

        if data_freq == 'daily':
            # If we're dealing with daily data, then we record
            # canonicalized timestamps, so make conversion here:
            oldest_hd_dt = normalize_date(oldest_hd_dt)
            penultimate_hd_dt = normalize_date(penultimate_hd_dt)
            penultimate_bts_dt = normalize_date(penultimate_bts_dt)

        self.assertEquals(prices_hd[oldest_hd_dt],
                          prices_bts[penultimate_bts_dt])
        self.assertEquals(prices_hd[penultimate_hd_dt],
                          prices_bts[newest_bts_dt])
コード例 #39
0
ファイル: assets.py プロジェクト: zhoulingjun/zipline
    def lookup_symbol_resolve_multiple(self, symbol, as_of_date=None):
        """
        Return matching Asset of name symbol in database.

        If multiple Assets are found and as_of_date is not set,
        raises MultipleSymbolsFound.

        If no Asset was active at as_of_date, and allow_expired is False
        raises SymbolNotFound.
        """
        if as_of_date is not None:
            as_of_date = pd.Timestamp(normalize_date(as_of_date))

        c = self.conn.cursor()

        if as_of_date:
            # If one SID exists for symbol, return that symbol
            t = (symbol, as_of_date.value, as_of_date.value)
            query = ("select sid from equities "
                     "where symbol=? "
                     "and start_date<=? "
                     "and end_date>=?")
            c.execute(query, t)
            candidates = c.fetchall()

            if len(candidates) == 1:
                return self._retrieve_equity(candidates[0][0])

            # If no SID exists for symbol, return SID with the
            # highest-but-not-over end_date
            if len(candidates) == 0:
                t = (symbol, as_of_date.value)
                query = ("select sid from equities "
                         "where symbol=? "
                         "and start_date<=? "
                         "order by end_date desc "
                         "limit 1")
                c.execute(query, t)
                data = c.fetchone()

                if data:
                    return self._retrieve_equity(data[0])

            # If multiple SIDs exist for symbol, return latest start_date with
            # end_date as a tie-breaker
            if len(candidates) > 1:
                t = (symbol, as_of_date.value)
                query = ("select sid from equities "
                         "where symbol=? " + "and start_date<=? " +
                         "order by start_date desc, end_date desc " +
                         "limit 1")
                c.execute(query, t)
                data = c.fetchone()

                if data:
                    return self._retrieve_equity(data[0])

            raise SymbolNotFound(symbol=symbol)

        else:
            t = (symbol, )
            query = ("select sid from equities where symbol=?")
            c.execute(query, t)
            data = c.fetchall()

            if len(data) == 1:
                return self._retrieve_equity(data[0][0])
            elif not data:
                raise SymbolNotFound(symbol=symbol)
            else:
                options = []
                for row in data:
                    sid = row[0]
                    asset = self._retrieve_equity(sid)
                    options.append(asset)
                raise MultipleSymbolsFound(symbol=symbol, options=options)
コード例 #40
0
ファイル: cumulative.py プロジェクト: cbonnett/zipline-fork
    def __init__(self,
                 sim_params,
                 env,
                 create_first_day_stats=False,
                 account=None):
        self.treasury_curves = env.treasury_curves
        self.start_date = sim_params.period_start.replace(hour=0,
                                                          minute=0,
                                                          second=0,
                                                          microsecond=0)
        self.end_date = sim_params.period_end.replace(hour=0,
                                                      minute=0,
                                                      second=0,
                                                      microsecond=0)

        self.trading_days = env.days_in_range(self.start_date, self.end_date)

        # Hold on to the trading day before the start,
        # used for index of the zero return value when forcing returns
        # on the first day.
        self.day_before_start = self.start_date - env.trading_days.freq

        last_day = normalize_date(sim_params.period_end)
        if last_day not in self.trading_days:
            last_day = pd.tseries.index.DatetimeIndex([last_day])
            self.trading_days = self.trading_days.append(last_day)

        self.sim_params = sim_params
        self.env = env

        self.create_first_day_stats = create_first_day_stats

        cont_index = self.trading_days

        self.cont_index = cont_index
        self.cont_len = len(self.cont_index)

        empty_cont = np.full(self.cont_len, np.nan)

        self.algorithm_returns_cont = empty_cont.copy()
        self.benchmark_returns_cont = empty_cont.copy()
        self.algorithm_cumulative_leverages_cont = empty_cont.copy()
        self.mean_returns_cont = empty_cont.copy()
        self.annualized_mean_returns_cont = empty_cont.copy()
        self.mean_benchmark_returns_cont = empty_cont.copy()
        self.annualized_mean_benchmark_returns_cont = empty_cont.copy()

        # The returns at a given time are read and reset from the respective
        # returns container.
        self.algorithm_returns = None
        self.benchmark_returns = None
        self.mean_returns = None
        self.annualized_mean_returns = None
        self.mean_benchmark_returns = None
        self.annualized_mean_benchmark_returns = None

        self.algorithm_cumulative_returns = empty_cont.copy()
        self.benchmark_cumulative_returns = empty_cont.copy()
        self.algorithm_cumulative_leverages = empty_cont.copy()
        self.excess_returns = empty_cont.copy()

        self.latest_dt_loc = 0
        self.latest_dt = cont_index[0]

        self.benchmark_volatility = empty_cont.copy()
        self.algorithm_volatility = empty_cont.copy()
        self.beta = empty_cont.copy()
        self.alpha = empty_cont.copy()
        self.sharpe = empty_cont.copy()
        self.downside_risk = empty_cont.copy()
        self.sortino = empty_cont.copy()
        self.information = empty_cont.copy()

        self.drawdowns = empty_cont.copy()
        self.max_drawdowns = empty_cont.copy()
        self.max_drawdown = 0
        self.max_leverages = empty_cont.copy()
        self.max_leverage = 0
        self.current_max = -np.inf
        self.daily_treasury = pd.Series(index=self.trading_days)
        self.treasury_period_return = np.nan

        self.num_trading_days = 0
コード例 #41
0
ファイル: index.py プロジェクト: joaonatali/pandas
    def _generate(cls,
                  start,
                  end,
                  periods,
                  name,
                  offset,
                  tz=None,
                  normalize=False):
        if com._count_not_none(start, end, periods) < 2:
            raise ValueError('Must specify two of start, end, or periods')

        _normalized = True

        if start is not None:
            start = Timestamp(start)

        if end is not None:
            end = Timestamp(end)

        inferred_tz = tools._infer_tzinfo(start, end)

        if tz is not None and inferred_tz is not None:
            assert (inferred_tz == tz)
        elif inferred_tz is not None:
            tz = inferred_tz

        tz = tools._maybe_get_tz(tz)

        if start is not None:
            if normalize:
                start = normalize_date(start)
                _normalized = True
            else:
                _normalized = _normalized and start.time() == _midnight

        if end is not None:
            if normalize:
                end = normalize_date(end)
                _normalized = True
            else:
                _normalized = _normalized and end.time() == _midnight

        if hasattr(offset, 'delta') and offset != offsets.Day():
            if inferred_tz is None and tz is not None:
                # naive dates
                if start is not None and start.tz is None:
                    start = start.tz_localize(tz)

                if end is not None and end.tz is None:
                    end = end.tz_localize(tz)

            if start and end:
                if start.tz is None and end.tz is not None:
                    start = start.tz_localize(end.tz)

                if end.tz is None and start.tz is not None:
                    end = end.tz_localize(start.tz)

            if (offset._should_cache()
                    and not (offset._normalize_cache and not _normalized)
                    and _naive_in_cache_range(start, end)):
                index = cls._cached_range(start,
                                          end,
                                          periods=periods,
                                          offset=offset,
                                          name=name)
            else:
                index = _generate_regular_range(start, end, periods, offset)

        else:

            if inferred_tz is None and tz is not None:
                # naive dates
                if start is not None and start.tz is not None:
                    start = start.replace(tzinfo=None)

                if end is not None and end.tz is not None:
                    end = end.replace(tzinfo=None)

            if start and end:
                if start.tz is None and end.tz is not None:
                    end = end.replace(tzinfo=None)

                if end.tz is None and start.tz is not None:
                    start = start.replace(tzinfo=None)

            if (offset._should_cache()
                    and not (offset._normalize_cache and not _normalized)
                    and _naive_in_cache_range(start, end)):
                index = cls._cached_range(start,
                                          end,
                                          periods=periods,
                                          offset=offset,
                                          name=name)
            else:
                index = _generate_regular_range(start, end, periods, offset)

            if tz is not None and getattr(index, 'tz', None) is None:
                index = lib.tz_localize_to_utc(com._ensure_int64(index), tz)
                index = index.view(_NS_DTYPE)

        index = index.view(cls)
        index.name = name
        index.offset = offset
        index.tz = tz

        return index