Commit Graph
41 Commits
Author SHA1 Message Date
jfkirk b84ac01cbf ENH: Adds futures trading and asset management logic to TradingAlgorithm and performance classes 2015-06-11 11:35:49 -04:00
Andrew Liang f44c15bb38 Scrubbing known warnings 2015-04-22 22:07:25 -04:00
Jonathan Kamens e942275108 STY: Flake8
Upgrade the version of the flake8, pep8, and mccabe PyPI packages, and
make the code changes necessary for compatibility with the updated
packages.
2015-03-19 17:21:25 -04:00
Dale Jung e908fa9f5c BUG: Initial digest frame was set with object dtype. Older verison of
numpy can error when expecting numeric dtypes and not np.array([1,2,3],
dtype=object)
2015-02-26 11:57:34 -05:00
Dale Jung 38e8d5214d PERF: History Perf Enhancements
Limited use of `pandas` data structures in both `HistoryContainer` and
`RollingPanel`. Where possible, methods were amended to return raw
`ndarrays` with the indexing logic done separately. This allows us to
cut down the number of times pandas objects are created both as returns
and intermediate values. The separation of indexing from data access
allowed us to minimize the times we’d make use of pandas indexes.

This required that that certain methods like `NDFrame.ffill` be replaced
with versions that work with `ndarrays`. Some of this was done via
straight numpy methods and others by access pandas internal
machinery. Outside of allowing us to use faster ndarrays, many of these
function provided speedups over their pandas counterparts as we didn’t
require the extra features like handling multiple dtypes. i.e. np.isnan
is faster than pd.isnull, but only works with certain dtypes.
2015-02-11 06:25:53 -05:00
Joe Jevnik e7a5e097c4 BUG: Explicitly guard against empty bar data in history container
contstruction.

BarData can be falsey. in create_buffer_panel, the intention of the
check against bar_data was to see if it was passed at all, not if it was
truthey. In order to make that check more explicit, the check now
asserts that bar_data is not None.
2014-11-19 11:55:13 -05:00
Joe Jevnik 9e94193d4b BUG: Off by one error in runtime construction of digest panel
When a history minute digest panel was constructed at runtime, there
would be 1 minute missing between the current minute at iloc[-1] and the
next prior minute at iloc[-2].
2014-11-18 11:22:17 -05:00
Joe Jevnik c2aae2e0f4 BUG: rolling panel data became misaligned after extend_back 2014-11-12 16:47:44 -05:00
Joe Jevnik 8df1a49031 BUG: When increasing the length dynamically, the rolling panel was
getting filled with the wrong datetimes and causing errors.

Updates the logic for addressing missing datetimes and adds unit tests
for the 2 main cases (no missing datetimes, and some missing datetimes).
2014-11-11 13:29:57 -05:00
Joe Jevnik 93429d69f5 BUG: HistoryContainer creation at runtime did not work as intended. 2014-11-05 18:31:11 -05:00
Joe Jevnik f8f7f2fc4c ENH: Allows history to be dynamic and grow the container at runtime.
Previously, all specs had to be pre-allocated by using the 'add_history'
function. This is now no longer required and instead serves as a hint to
the HistoryContainer to pre-allocate the space for the given spec.

History can grow by increasing the length for a frequency, adding a
frequency, or adding a field. It can grow with any combination of
these.

HistoryContainer now is aware of the data_frequency of the algorithm,
and no longer uses the daily_at_midnight flag; instead, this is the
default behavior.
2014-11-03 15:57:44 -05:00
Thomas Wiecki 18ad02f6a4 MAINT: Make len check for ffillable explicit. 2014-10-22 17:25:37 +02:00
Scott Sanderson 76c32f2940 PERF: Use np.empty instead of np.ones.
No reason to use ones when we multiply everything by NaN immediately.
2014-10-18 16:49:27 -04:00
Scott Sanderson 7104725e3c DEV: Cleanup from PR comments.
Flip axes of numpy array in frame_from_bardata.
Add default=None to SidData.get.
2014-10-17 11:55:30 -04:00
Scott Sanderson 30c4a1a1dc PERF: Optimized rewrite of HistoryContainer.update.
Uses a numpy array instead of a dict of dicts when initializing history
container.

In testing this reduced the total time spent in HistoryContainer.update
by 66%.

BEFORE COMMIT:
Thu Oct 16 22:30:46 2014    results/cprofile/unoptimized

         185223320 function calls (182210491 primitive calls) in 401.351
         seconds

   Ordered by: cumulative time
   List reduced from 2398 to 27 due to restriction <'update'>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     8580    0.461    0.000  160.571    0.019
     qexec/zipline/history/history_container.py:388(update)

AFTER COMMIT:
Thu Oct 16 22:12:28 2014    results/cprofile/optimized

         143177181 function calls (140164352 primitive calls) in 272.403
         seconds

   Ordered by: cumulative time
   List reduced from 2395 to 27 due to restriction <'update'>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     8580    0.086    0.000   47.294    0.006 qexec/zipline/history/history_container.py:388(update)
2014-10-16 22:32:43 -04:00
Scott Sanderson 028ba719a2 BUG: Fix numpy dtype casting bug that only manifests in pandas 0.14.0. 2014-10-02 18:09:51 -04:00
Scott Sanderson d52dc68b5a PERF: Use numpy functions for concatenation in history. 2014-10-02 16:10:56 -04:00
Scott Sanderson 19d97524da PERF: Don't apply lambdas to large DataFrames. 2014-10-02 11:12:51 -04:00
Scott Sanderson 235954d480 DEV: Overhaul core history logic.
Overhaul the core HistoryContainer logic to be more robust to changing
universes.

Major Changes
-------------
* Remove `return_frame` cache.  The original purpose of using
  return_frames was to avoid having to create new DataFrames on each
  iteration of handle_data, but we ended up having to copy the return
  frames anyway because user code could mutate the frames in place.
  Removing the return_frames reduces unnecessary copying, and reduces
  the logic of `get_history` to just forward-filling and concatenating
  two DataFrames.

* Use a `MultiIndex`ed DataFrame to represent
  `last_known_prior_values`.  This makes lookups faster and greatly
  simplifies the logic of adding and dropping sids.

* HistoryContainer no longer attempts to determine its universe based on
  the contents of its internal buffers.  The TradingAlgorithm
  controlling the container is now responsible for explicitly calling
  `add_sids` or `drop_sids` when securities enter or leave the
  algorithm's universe.  These methods, along with the internal
  `_realign` method, provide a clean interface for changing the universe
  of securities managed by the container.

* Refactor index mutation logic in `RollingPanel` into a
  `MutableIndexRollingPanel` subclass.  Maintenance of the old behavior
  is regrettably necessary to support `BatchTransform`.

* Refactor shared logic from `roll` and `get_history` into a single
  `aggregate_ohlcv_panel` method that's responsible for collapsing an
  OHLCV buffer into a frame.
2014-09-29 14:42:57 -04:00
Scott Sanderson fcb137e0bb DOC: Clarificatory comments in HistoryContainer. 2014-09-29 14:40:03 -04:00
Scott Sanderson 9152d8da37 DOC: Slightly better comment on Frequency._ffill. 2014-09-29 14:40:03 -04:00
Scott Sanderson c477680ca3 MAINT: Use filter builtin instead of if-statement and continue. 2014-09-29 14:40:02 -04:00
Scott Sanderson 94b53bdcb7 MAINT: Minor tweaks to docstring. 2014-09-29 14:31:57 -04:00
Scott Sanderson fd71f956c7 DOC: Add more information to IncompatibleHistoryFrequency message. 2014-09-19 23:48:55 -04:00
Thomas Wiecki 4615b57fc2 MAINT: Add custom exception for incompatible history frequency specification. 2014-09-18 16:20:28 +02:00
Thomas Wiecki 5490349c62 MAINT: Test frequency.unit_str instead of frequency string. 2014-09-17 18:17:11 +02:00
Thomas Wiecki 011f072fe2 MAINT: Add assertion for incompatible history freq specification. Supplying 1m frequency to history but only providing daily source data resulted in an odd non-descript exception. This adds a specific check and raises a more informative exception. 2014-09-17 15:04:37 +02:00
Eddie Hebert 3c8363722e MAINT: Log more information on history update failure.
Log the field and algo datetime when the update of the return frame
fails; re-raise the error until the when and why of the value error is
understood.
2014-08-05 12:17:00 -04:00
Thomas Wiecki 845712e5eb MAINT: Factor out column conversion in HistoryContainer.
We can't be sure that security identifiers can be converted
to int. In fact, most of the times they are strings. This
adds an identity function that can be overwritten if such
a conversion is necessary (as on Quantopian).
2014-07-16 15:17:02 +02:00
Thomas Wiecki 6de4d32ee1 ENH: Change open and close to midnight if using daily input data. 2014-07-16 15:16:57 +02:00
Scott Sanderson 75b415ac48 BUG: Algo no longer crashes after creating new history column.
Fixes an issue that caused a crash if a user assigned a new column into a
returned history DataFrame.  This occurred because we re-use DataFrames between
history() calls, so the new column caused an index-size mismatch on the next
attempted calculation.

Ideally we would fix this by in-place dropping the columns, but that isn't
supported in pandas 0.12.0, so instead we just return a complete copy of the
frame.  We should re-evaluate this implementation when we're on a more modern
pandas version.
2014-06-30 12:09:03 -04:00
Scott Sanderson 6a2ee7c417 BUG: History no longer fails on length-1 '1m' price-only HistorySpecs
The bug occurred because there is a special case in the initial window setup
code for handling the case where only a length-1 history is used for a given
frequency.  Previously, the code was incorrectly calculating the period end
using a hard-coded expression for the end of the day (the correct behavior for
a length-1 '1d' history), and then using the frequency object to calculate the
period start for the window.  In the case of length 1 '1m' data, this resulted
in an initial window whose start and end was the last minute of the day rather
than the first minute of the day.  For non-price fields, this error doesn't
matter, because the window is only used for rolling digests (which doesn't
happen when there's only a length-1 history), and for the forward-filling logic
(which only happens on price fields).  For a length-1 '1m' price, however, the
incorrect window causes us to attempt to forward-fill an empty panel, resulting
in an IndexError when we do an iloc[0] on a length-0 axis.
2014-06-25 10:54:45 -04:00
Scott Sanderson 79c91897ba ENH: Add freq_filter argument to HistoryContainer.update_digest_panels.
Adds a new argument, `freq_filter`, to `HistoryContainer.update_digest_panels`,
which can be used to supply a predicate determining which digest panels are
updated by the call.  This is useful for supporting initialization/backfilling
of multi-frequency panels in subclasses.
2014-06-09 17:42:41 -04:00
Scott Sanderson 7995e6ac0d DOC: Tweaks to docstrings in history.py and history_container.py. 2014-06-09 17:40:57 -04:00
Scott Sanderson cfe00b0c37 ENH/TEST: Enable '1m' history and add tests for the frequency. 2014-06-05 15:25:49 -04:00
Scott Sanderson 3a1fc1032e ENH: Overhaul logic in HistoryContainer.
Updates `HistoryContainer.roll` to handle cases where no data is present for
the period being rolled.

We now only forward-fill the `price` field when `ffill` is specified.
2014-06-05 15:25:49 -04:00
Scott Sanderson 15f1947652 BUG: Don't return mostly nans from get_history when ffill=False.
Fixes an issue where, if `ffill=False`, `get_history` would return nans for
every entry in the history frame except the last one.
2014-06-05 15:25:49 -04:00
Scott Sanderson bad4c9a439 ENH: Prep work for supporting '1m' history.
Overhauls `HistoryContainer` in prep for support of more than one frequency.

Major changes:

   - Methods/variables referring to "day" have been renamed/generalized.
     - `current_day_panel` became `buffer_panel`, which is now a `RollingPanel`
     - `prior_day_panel` became a dictionary mapping `Frequency` objects to
       "digest panels", which are instances of `RollingPanel`.

   - Hard-coded daily rollover replaced with a notion of a "current window" for
     each unique frequency managed by the panel.

     - When the end of the current window is reached for a given frequency, we
       compute an aggregate bar (code refers to this as a "digest"), which is
       appended to a panel associated with that frequency.

     - Window rollover dates are managed by a pair of dictionaries,
       `cur_window_starts` and `cur_window_closes`.  The `Frequency` class is
       responsible for computing window bounds based on the open/close of the
       previous window.

   - Semantic change to the `open_price` field: `open_price` now always
     contains the price of the first trade occurring in the given window.
     Previously it contained the price of the first minute in the window,
     returning NaN it the security happened not to trade in the first minute.
2014-06-05 15:25:48 -04:00
Scott Sanderson 5392506d6d DOC: Documentation fixups in history_container.py. 2014-06-05 11:15:50 -04:00
twiecki e261438d01 ENH: Adapt history() to work on zipline. 2014-04-10 15:59:26 -04:00
Eddie Hebert c9b1a3f1c7 WIP: Initial port of history. 2014-04-10 15:58:47 -04:00