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.
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.
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.
The next day calculation was causing an error when a minute
emission algorithm reached the end of available data.
Instead of a generic exception when available data is reached,
raise and catch a named exception so that the tradesimulation loop
can skip over, since the next market close is not needed at the end.
The __repr__ for RiskMetricsCumulative was referring to an older
structure of the class, causing an exception when printed.
Convert to printing the last values in the metrics DataFrame.
To help prevent algorithms from operating on positions that are
not in the existing universe of stocks.
Formerly, iterating over positions would return positions for stocks
which had zero shares held. (Where an explicit check in algorithm
code for `pos.amount != 0` could prevent from using a non-existent
position.)
Use six's with_metaclass to have objects that use metaclasses, in
both Python 2 and 3.
Otherwise, in Python 3 the objects were being treated as if they
did not have a metaclass, when the Python 2 syntax is used, leading
to errors because of missing attributes, etc.
Python 3 requires submodules to have more explicit pathing, so use
the dot syntax to declare submodules which are in the same directory
as another module.
Use the six module to import functions and types that are
consistent between Python 2 and 3, so that one code base can
support both versions.
- Use integer types instead of int and long.
- Use string_types instead of basestring.
- Account for iteritems, itervalues, iterkeys.
- Use six.moves for filter and zip, reduce
- Use compatible bytes for md5 hasher.
- xrange and range
The market_open_and_close method was a performance bottleneck,
since it was creating new dates on each query for open and close.
Instead use the pre-rendered frame of open and closes values
from the trading environment.
In the performance period the max_leverage, max_capital_used,
cumulative_capital_used were calculated but not used.
At least one of those calculations, max_leverage, was causing a
divide by zero error.
Instead of papering over that error, the entire calculation was
a bit suspect so removing, with possibility of adding it back in
later with handling the case (or raising appropriate errors) when
the algorithm has little cash on hand.
Instead of nesting order direction and related stop and limit logic,
derive a bitwise mask from the combination of order configurations
and use the mask as a 'switch'.
Remove the lists of DailyReturn objects in favor of using pd.Series
to store the return values.
Should make it easier to inspect the values when stepping through,
make the windowing of data to a certain range more facile by using,
and have some performance increases due to removing object creation
and member access.
This reverts commit 17b8980fb9.
Backing out rigidness of market and close, while sorting out how
to handle events that are not on a day in the trading calendar.
Instead of creating the market open and close mid-simulation,
calculate upfront the values for market open and close in a
DataFrame, so that they values can be looked up by date, as
viewed as series while investigating data issues.
One downside of this implementation is that the entire history
has open and close values calculated, even though the simulation
may only be a subset of the trade data on record.
Should consider moving the `times` property and other methods
that care about the start and end date of a simulation to
SimulationParameters or another like object.
Instead of using all calendar days between start and end in test
sources, use the trading calendar for test sources.
Needed for an incoming refactoring of market open and close,
where the opens and closes are indexed by market days.
So that with minute data, 2.5 orders of magnitude of data can
be cut, allowing for longer window_lenghts, when the daily
values are what are desired for a signal.
So that the units match the other risk calculations, also
use annualized returns for beat and alpha.
Update answer key to match values calculated on the first day.
Also, update performance tracker test so that the returns used
are fractional instead of > 1, so that the annualized numbers are
more in line with real world values.
This could perhaps be labelled BUG, as well.
Change the Sharpe (and algorithm volatiilty) value used to compare
algorithms/backtests so that it is annualized and uses daily returns.
Previously, the Sharpe metric was using the same calculation style
as the fixed size periods, i.e. 3 Month, 6 Month, etc., which can
use the geometric mean when comparing against the risk free.
Change the Sharpe calculation to use the arithmetic mean differenc
against the risk free rate, using daily (non-compounded) values.
Also, use annualized mean returns.