Commit Graph
522 Commits
Author SHA1 Message Date
Delaney Granizo-Mackenzie 0fd78cd54a BUG: Fixed random dips in returns as shown to user.
Previously the last sale price was not correctly being set on
positions when the transaction arrived before the trade event.
The last sale price was defaulted to zero and never updated. This resulted
in one holding stocks that were bough >>0 and now had value 0 from
the perspective of returns. The returns would display correctly again
when the next trade of that security happened. For most securities trading is
frequent enough that there's no issue, but for some illiquid ones it took
hours to fix itself.

Updated test_perf_tracking:TestPerformanceTracker.test_minute_tracker
This test was based on assuming that last_sale_price was zero,
allowing the sharpe ratio to be calculated. The sharpe ratio can no longer
be calculated for this specific tested scenario and the test has been changed
accordingly.
2014-07-29 11:07:13 -04:00
Scott Sanderson d610ea0a3b DOC: Rename 'guid' to 'id' in dividend tracking logic. 2014-07-18 15:04:20 -04:00
Scott Sanderson 4712891e88 ENH: Remove dividends from the event stream.
Removes support for handling dividends as part of the algorithm
simulation stream, replacing it with an API in `TradingAlgorithm` for
supplying dividends as a DataFrame.
2014-07-18 15:04:20 -04:00
Scott Sanderson a8431944aa MAINT: Add comments and rename methods in PerformanceTracker.
The function that handles a market close for daily frequency changed from
`handle_market_close` to `handle_market_close_daily`.

The function that is called at on the closing minute each day when running
minutely changed from `handle_intraday_close` to
`handle_intraday_market_close`.
2014-07-18 15:04:20 -04:00
Thomas Wiecki 8d09305c36 BUG: Fix constant of trading hours to be 6.5. Fixes #214. 2014-07-02 11:26:35 +02:00
Thomas Wiecki 10885e1b77 MAINT: One way to set sim_params and data_frequency.
There were sevaral places you could supply sim_params
in TradingAlgorithm (__init__, run). This got confusing
as its not clear who updated what and which one was the
correct one to use at each time.

Then there were to ways to define data_frequency, one in
__init__() and one in the sim_params which also added code
complexity.

This refactor makes it explicit that sim_params are to be
passed to __init__() only. Moreover, data_frequency is
only stored in sim_params. For backwards compatibility,
it can still be supplied separately but will link to
the one in sim_params.

For example, you could create new sim params via:

sim_params = create_simulation_parameters(data_frequency='minute')
algo = MyAlgo(sim_params)
algo.run(data)

In addition, perf_tracker only gets initialized in one place:
_create_generator() which should also make the various ways
of running an algorithm more deterministic.

This also fixes a bug with SimulationParameters where
you could not change the period_start. Unfortunately, the
current implementation still requieres an implicit call to
update the internal variables.
2014-06-30 17:28:02 +02:00
Scott Sanderson 4c9cf1321d PERF: Replace .ix usages with with .loc in TradingEnvironment.
Replace usage of .ix in TradingEnvironment with .loc when we know that we're
using an index key.

DataFrame.ix can be used with either integer or key-based indices, and as such
it incurs an overhead for figuring out which you meant.
2014-06-26 17:17:08 -04:00
Scott Sanderson 49eaeeb6ae BUG: Apply integer truncation to order amounts earlier in the pipeline.
Truncate non-integer order amounts in `TradingAlgorithm.order` instead of
`Blotter.order`.  This fixes an issue where non-integer orders coming out of
order_value can spuriously trigger a `LongOnly` trading guard.

Example:

sid.price == 2.0
order_value(sid, 5) -> order(sid, 2.5) -> truncated to order(sid, 2.0)
order_value(sid, -5) -> order(sid, -2.5) -> LongOnlyViolation b/c 2.0 - 2.5 < 0
2014-06-09 11:42:43 -04:00
Scott Sanderson b6e5345893 ENH: Enhancements to TradingEnvironment.
Adds a suite of new functions for querying data from the trading calendar.

These include:
      `previous_trading_day`
      `minutes_for_days_in_range` (minutely version of `days_in_range`)
      `previous_open_and_close` (inverse of `next_open_and_close`)
      `next_market_minute`
      `previous_market_minute`
      `open_close_window` (get a range of opens/closes with slicing semantics)
      `market_minute_window` (get a range of minutes with slicing semantics)

Also refactors `test_finance` to move `TradingEnvironment` tests into their own
TestCase.
2014-06-05 15:25:48 -04:00
Scott SandersonandEddie Hebert 7daf58ec9b ENH: Add a class-level instance method on TradingEnvironment.
Adds a classmethod, `instance` on `TradingEnvironment` that returns
`zipline.finance.trading.environment`, instantiating it if necessary.

This makes it possible to initialize the default environment instance in a
less-roundabout way than creating a `SimulationParameters` object.
2014-06-05 12:02:53 -04:00
Thomas Wiecki 40001f3509 STY: Remove warning when ordering zero shares.
Many algorithms that use the new order methods like order_target()
will legitimately try to order 0 shares many times. The printed
warning at every turn is quite annoying and too verbose. We do not
display it on Quantopian either so I'm removing it here as well.
2014-06-02 15:50:21 +02:00
Scott Sanderson ecd9bff0d6 PERF/BUG: Make the portfolio property call updated_portfolio.
Make the portfolio property on TradingAlgorithm call `updated_portfolio`
internally.  This prevents needless recomputation of the portfolio between
calls to `handle_data`, and also prevents issues where the portfolio object
could be unexpectedly modified in place in the body of a `handle_data` call.

Noteworthy finding in the course of investigating this bug:

If you modify a Python dictionary while iterating over it, the language will
only throw an exception if the size of the dictionary changes between loop
iterations; this means that you can do:
```
x = {1:1, 2:2, 3:3}
for k in x:
    old_val = x[k]
    del x[k]
    x[f(k)] = old_val
    print k
```
and you'll only get an error if f(k) is already a key in the dictionary.
This can lead to bizarre/nondeterministic behavior in the key iterator.
2014-05-27 11:20:13 -04:00
Scott Sanderson 644486e6da ENH: Add trading controls to zipline API.
Adds four new methods to the Zipline API that can be used as circuit-breakers
to interrupt the execution of an algorithm.  The API methods are:

`set_max_position_size`
`set_max_order_size`
`set_max_order_count`
`set_long_only`

Internally, these methods are implemented by each registering a TradingControl
callback object with the TradingAlgorithm.  During
TradingAlgorithm.__validate_order_params (and thus before any side-effects of
the order call occur), each callback's `validate` method is called with
information about the order to be placed and the algorithm's current state,
raising an exception if the callback detects that an error condition has been breached.
2014-05-12 17:51:09 -04:00
Pankaj GargandEddie Hebert 6e9dc6e552 BUG: Use env_trading_calender for open and closes data
TradingEnvironment class uses env_trading_calendar for trading days,
but the default trading calendar for open_and_close data, which causes
errors later, because of misalignment of trading days.

The issue can be resolved by using env_trading_calendar for
open_and_closes as well
2014-05-12 14:29:21 -04:00
Scott Sanderson f41c37a606 ENH: Add the ability to specify an exchange on an ExecutionStyle.
Adds the exchange property the interface for ExecutionStyle and adds an
exchange parameter to the interface of all the existing ExceutionStyles.
Subclasses wishing to support the ability to specify an exchange should set the
_exchange attribute in __init__.
2014-04-29 17:35:12 -04:00
Scott Sanderson 5373b6797c ENH: Treat stop and limit prices differently when rounding.
Stop and limit prices both trigger when a price crosses some threshold, but
they trigger in "opposite directions".  For example, on a buy, a limit price is
triggered when a price falls below a specified value, whereas a stop price
triggers when the price exceeds a specified value.

Our current stop/limit price rounding logic is asymmetric, preferring to "round
to improve" the specified price.  This change makes it so that we interpret
"improvement" in opposite directions for stop vs limit prices.
2014-04-25 12:02:23 -04:00
Richard Frank 17df628171 DOC: Replaced "i.e." with "e.g." where appropriate in module 2014-04-24 14:01:05 -04:00
Richard Frank f21bbe58fc ENH: Allow for stock dividends, and in particular, Google's
recent 2 for 1 stock split, where 1 class C share was distributed
for each share of class A held.

Now a dividend can specify a sid and ratio of stock that will be paid
to owners of the original security.  If the ratio is 2.0, then for every
existing share, two shares will be paid.
2014-04-24 14:00:39 -04:00
Scott Sanderson 119a1a4cda ENH: Update ordering API to support new ExecutionStyle class in favor of
existing `limit_price` and `stop_price` parameters.  The goal of this change is
to refactor the existing ordering API to provide a cleaner interface for
defining more complex order types.

Adds a new module, zipline.finance.execution, which defines the ExecutionStyle
abstract base class, along with concrete MarketOrder, LimitOrder, StopOrder,
and StopLimitOrder subclasses.

Adds a new `style` keyword argument to the function signature of the `order`
API method, which accepts an instance of ExecutionStyle.

The existing limit_price and stop_price parameters are still supported at this
time, but are converted into the new ExecutionStyle objects before being passed
to Blotter.order.
2014-04-22 23:22:21 -04:00
Scott Sanderson 353419e9ca BUG: Fix __unicode__ method for Order class in blotter.py
Order's __unicode__ was previously calling unicode(self.__repr__) instead of
actually calling the repr method.
2014-04-22 10:58:30 -04:00
Scott Sanderson eadf9d27e8 BUG: Fix a bug causing us to discard very low limit prices.
Fixes an issue where very low limit prices were being rounded to 0.0 and
effectively resulting in market orders.  Adds an explicit check to test for
this behavior.
2014-04-22 10:12:50 -04:00
Scott Sanderson 574415f434 MAINT: Adding tests for Blotter handling of limit and stop orders.
Adds a test algorithm that tries to buy with very high limit prices/very low
stop prices and tries to sell with very low limit prices/very high stop prices.
2014-04-21 16:34:59 -04:00
Eddie Hebert 73573680f1 MAINT: Remove unneeded parameter to cumulative.calculate_alpha
The method was using a mix of the `dt` parameter and `self.latest_dt`.
Use `self.latest_dt` to conform with the rest of the module.
2014-04-17 11:19:45 -04:00
Eddie Hebert 35b09690a1 STY: Conform indentation to current flake8 recommendation.
The lines will be moved back when flake8, pyflakes, and pep8 are
all upgraded to latest.
2014-04-16 16:49:54 -04:00
Eddie Hebert acd0aeacf0 PERF: Reduce number of times the downside mask is created.
Assign the downside mask, `rets < mar` to a value instead of
calculating the downsides twice.
2014-04-16 16:25:02 -04:00
Eddie Hebert 1406f8e9ba PERF: Remove the drop of 'null return' from cumulative returns.
The check of existence of the null return key, and the drop of said
return on every single bar was adding unneeded CPU time when an
algorithm was run with minute emissions.

Instead, add the 0.0 return with an index of the trading day before
the start date.

The removal of the `null return` was mainly in place so that the
period calculation was not crashing on a non-date index value;
with the index as a date, the period return can also approximate
volatility (even though the that volatility has high noise-to-signal
strength because it uses only two values as an input.)
2014-04-16 15:48:13 -04:00
Eddie Hebert 101baad0f8 BUG: Fix change of type of period.sharpe
The factoring out of the Sharpe calculation changed behavior
so that both period and cumulative return nans when there is
no volatility; however before that change period returned 0.0.

This breaks existing consumers which expected a non-nan value
for period results.

Smooth out that change by checking the value after the sharpe
has been calculated and reset nan's to 0.0
2014-04-14 18:45:33 -04:00
Eddie Hebert 7cc24cec1f BUG: Fix numerous cumulative and period risk calculations.
The calculations that are expected to change are:
- cumulative.beta
- cumulative.alpha
- cumulative.information
- cumulative.sharpe
- period.sortino

* Explanation of how risk calculations are changing

** Risk Fixes for Both Period and Cumulative

*** Downside Risk

   Use sample instead of population for standard deviation.

   Add a rounding factor, so that if the two values are close for a given
   dt, that they do not count as a downside value, which would throw off
   the denominator of the standard deviation of the downside diffs.

*** Standard Deviation Type

    Across the board the standard deviation has been standardized to using
    a 'sample' calculation, whereas before cumulative risk was monstly using
    'population'. Using `ddof=1` with `np.std` calculates as if the values
    are a sample.

** Cumulative Risk Fixes

*** Beta

   Use the daily algorithm returns and benchmarks instead of annualized
   mean returns.

*** Volatility

   Use sample instead of population with standard deviation.

   The volatility is an input to other calculations so this change affects
   Sharpe and Information ratio calculations.

*** Information Ratio

   The benchmark returns input is changed from annualized benchmark returns
   to the annualized mean returns.

*** Alpha

   The benchmark returns input is changed from annualized benchmark returns
   to the annualized mean returns.

** Period Risk Fixes

*** Sortino

    Use the downside risk of the daily return vs. the mean algorithm returns
    for the minimum acceptable return instead of the treasury return.

    The above required adding the calculation of the mean algorithm returns
    for period risk.

    Also, use algorithm_period_returns and tresaury_period_return as the
    cumulative Sortino does, instead of using algorithm returns for both
    inputs into the Sortino calculation.

* Other Supporting Changes

** answer_key

   Add new mappings for downside risk and Sortino as well as
   re-address the index mappings because of changes to the answer key
   spread sheet.

** test_risk_cumulative

   Change the decimal precision to expect higher precision.
   The calculations are now more aligned with the answer key, so we can
   expect higher precision. In particular now that the standard deviation
   type matches everywhere in both the Python implementation and the answer
   sheet, the precision of the first value no longer has to be glossed over.

** test_events_through_risk

  Change the results which are used as a canary for risk changes,
  since we do expect Sharpe to change with this change..
2014-04-14 16:44:28 -04:00
twiecki e261438d01 ENH: Adapt history() to work on zipline. 2014-04-10 15:59:26 -04:00
twiecki 5cb2919b10 STY: pep8 fixes. 2014-04-10 10:57:12 -04:00
Eddie Hebert 4bf8ab0f8d ENH: Remove dependency on benchmark for trading day calendar.
Instead of the benchmarks' index, use the trading calendar to
populate the environment's trading days.

Remove `extra_date` field, since unlike the benchmarks list,
the trading calendar can generate future dates, so dates for
current day trading do not need to be appended.

Motivations:
- The source for the open and close/early close calendar and the
  trading day calendar is now the same, which should help prevent
  potential issues due to misalignment.
- Allows configurations where the benchmark is provided as a
  generator based data source to need to supply a second benchmark
  list just to populate dates.
2014-04-01 21:14:39 -04:00
Eddie Hebert b5dbaf88d1 BUG: Prevent out of sync market closes in performance tracker.
In situations where the performance tracker has been reset or patched
to handle state juggling with warming up live data, the `market_close`
member of the performance tracker could end up out of sync with the
current algo time as determined by the

The symptom was dividends never triggering, because the end of day
checks would not match the current time.

Fix by having the tradesimulation loop be responsible, in minute/minute
mode, for advancing the market close and passing that value to the
performance tracker, instead of having the market close advanced by
the performance tracker as well.
2014-03-30 13:33:45 -04:00
Eddie Hebert 95b379d567 BUG: Fix misalignment of downside series calc when using exact dates.
An oddity that was exposed while working on making the return series
passed to the risk module more exact, the series comparison between
the returns and mean returns was unbalanced, because the mean returns
were not masked down to the downside data points; however, in most,
if not all cases this was papered over by the call to `.valid()`
2014-03-27 20:51:48 -04:00
twiecki 4bdecd6402 STY: PEP8 fixes. 2014-03-26 20:46:20 +09:00
Eddie Hebert 51750a3a35 MAINT: Factor out downside risk calculation.
Move the downside risk calculation into the main risk module;
so that the same calculation can eventually be used by both
the period and cumulative calculations, to prevent implementation
drift.
2014-03-25 13:23:08 -04:00
Eddie Hebert 51c8a310be MAINT: Remove unused members of TradingEnvironment.
The following members are no longer referenced elsewhere:
- `full_trading_day`
- `early_close_trading_day`
2014-03-24 21:56:17 -04:00
Richard Frank a6184b87e3 MAINT: Set initial values so to_dict can be called immediately
Previously, it would raise an exception.
2014-03-24 15:44:46 -04:00
Richard Frank bb50d996ed MAINT: Using dictionary literal syntax and combining lines
for readability
2014-03-24 15:44:46 -04:00
Eddie Hebert 803b58c8aa MAINT: More precise extraction of returns from returns container.
Use slice to date, `[:dt]` instead of `pd.Series.valid` to extract
from returns containers.

Using `valid` lead to some confusion when debugging tests, because
it papers over missing data.

The use of `.valid` was based on the assumption that all values
from the zeroth date to the current algo date are populated,
with no trailing values.
`[:dt]` extracts the same data, but in a hopefully more precise
and explicit fashion.
2014-03-21 17:22:10 -04:00
Eddie Hebert 7ce971fa17 MAINT: Use more clearly named cumulative risk returns containers.
Change `_period_returns` to `_cumulative_returns`, so that there
is less mental overhead/confusion when reading through the risk
module.
2014-03-20 16:00:34 -04:00
Richard Frank 7a3f73cf1d BUG: Update perf period state when positions are changed by splits
Otherwise, self._position_amounts will be out of sync with position.amount, etc.
That value is used to calculate pnl and returns, so test for them.
2014-03-11 19:08:22 -04:00
Eddie Hebert 4860a966b3 REL: Update copyright year on all files changed since the new year. 2014-03-07 22:31:41 -05:00
twieckiandEddie Hebert 778da20468 BUG: Fix floating point error in order(). 2014-03-06 12:32:19 -05:00
Richard Frank 5020c36f8d BUG: Fix cost basis calculation
Cost basis calculation now takes direction of txn into account.

Closing a long position or covering a short shouldn't affect the cost basis.
2014-03-05 14:48:58 -05:00
Richard Frank e7ec629510 MAINT: Cleaned up sid checks and exception types
Removed unnecessary parens

Keeping NameError reserved for when locals or globals are not found.
Exception is what we use for the other sid checks, so now they are consistent.
2014-03-05 14:40:05 -05:00
Richard Frank 76b11e8b84 MAINT: Removed unnecessary floating point checks in slippage
Cleaned up some other expressions in slippage as well

Fixes #277
2014-03-04 18:36:29 -05:00
Eddie Hebert 6cdd5ddb10 BUG: Fix max drawdown calculation.
The input into max drawdown was incorrect, causing the bad results.
i.e. the `compounded_log_returns` were not values representative of
the algorithms total return at a given time, though
`calculate_max_drawdown` was treating the values as if they were.
Instead, use the `algorithm_period_returns` series, which does provide
the total return.

Update risk answer key with an Excel calculation of max drawdown
to help corroborate the calculations.

Also, remove `compounded_log_returns`, (which actually had stopped
being the `compounded_log_returns` at some point), since the max
drawdown was the only calculation using the values in that series.
2014-02-27 17:16:35 -05:00
Eddie Hebert e3096e9afc MAINT: Remove unused rounding method.
round_to_nearest is no longer referred elsewhere.
2014-02-26 21:55:14 -05:00
Eddie Hebert 7f724a9696 ENH: Provide all drawdowns and max drawdowns in cumulative risk.
The values are not part of the risk report, but can be useful for
examining the behavior of the drawdown calculations.
2014-02-26 20:46:58 -05:00
Colin AlexanderandEddie Hebert 011ed09dc2 ENH: Extended commission PerShare method to allow a minimum cost per trade.
Also added unit tests (test_perf_tracking.TestCommissionEvents) to test
all commission models.
2014-02-25 14:37:08 -05:00