Previously, on the dt of a capital change, we use the un-updated
prices to find the ending performance of the previous subperiod and
then got the new prices to determine the portfolio value used to
calculate the delta, without actually updating the performance
before applying the capital change. This logic is confusing and
unintuitive. Instead, save the ending performance as we do previously,
but have temp values for the starting current subperiod value.
Update those temp values after processing the capital change
AlgorithmSimulator will no longer check for capital changes.
Instead, TradingAlgorithm find and calculate the changes, and
PerformanceTracker will apply the changes
Instead of having separate ExchangeCalendar and TradingSchedule objects, we
now just have TradingCalendar. The TradingCalendar keeps track of each
session (defined as a contiguous set of minutes between an open and a close).
It's also responsible for handling the grouping logic of any given minute
to its containing session, or the next/previous session if it's not a market
minute for the given calendar.
Refactor AlgorithmSimulator so that DAY_END is emitted for both
minute and daily emission, and that handling of end-of-minute
and end-of-day are separated
In preparation for the incoming changes which no longer push every bar
through the tradesimulation, remove the adjustment of the period's cash on
every pricing change of a held futures asset.
Instead hold the last sale price for each held future either:
- At the end of each peformance period update the last sale prices of
all held futures, so that the pnl for the next period uses values
derived from the cash difference between the end of the two periods.
- When a transaction is processed for the Future, so that the correct
amount is applied to each cash adjustment. (i.e. the cash adjustment
is reset on every change of amount of the Future being held, so that
multiple size and prices do not need to be tracked for the same asset.)
Also, remove now unused dict of payout calculation modifier, since new
calculation reads the value directly off of the asset.
Remove update_last_sale test, since the method no longer returns a cash
value.
In preparation for removal of widespread events, change the commission
methods to use params for sid and cost, instead of an event, for
compatibility with lazy branch.
co-author: @jbredeche <jean@quantopian.com>
Refer to cumulative and todays performance explicitly instead of always
looping through.
The third value (minute) for which this was useful, has been removed.
Also, there are some actions where only cumulative may need application,
e.g. application of dividends. (However, this patch does not remove
dividend processing from todays performance, but opens up later patches
to make that distinction.)
This commit removes the ability to reference a shared TradingEnvironment through the zipline.finance.trading module. In place, the classes that require a TradingEnvironment, or its child AssetFinder, contain their own references to those objects.
This commit also adds serialization utilities that allow for the pickling/unpickling of objects without unintentionally their TradingEnvironments or AssetFinders.
The minutely calculation of risk metrics had been removed with a
previous patch, remove vestigial references.
Remove a test which tested the behavior of updating the second minute of
a day.
Remove the logic that changed the datetime index of the risk metrics
depending on emission rate, now only trading_days are needed.
Remove `returns_frequency` parameter since both minute and daily
data frequency always use daily returns.
Instead of using the pandas.Series datetime index for every single
vector, get the index at the beginning of the update loop based on the
dt and then use that index to set the values.
Also, since the dt lookup is no longer needed, store the values as numpy
arrays, which are more lightweight.
Locally, this patch cuts out about 60% of the time spent in the update
method.
Referencing context.account in handle_data() can block updates to account,
portfolio and performance metrics, which can cause unintended changes in
financial performance. Additionally, since context.account metrics are not
updating frequenctly enough (daily, rather than minutely) algos which base
decisions on these metrics can have undesired behavior.
To address this we do not base our decision to update performance on the
state of account_needs_update.
When we call get_account() from the market and minute close methods, we
set the performance_needs_update parameter to False since we just updated
performance.
_get_account() is renamed to _update_account() since the method does not
return account information.
Also remove redundant asset_needs_update = True lines.
By having both the trade simulation main loop route events to "process"
methods based on event type and the process methods also checking event
type, there was some duplicated effort in doing that comparison many
times.
A particular case where this was noted in profiling was for the
`process_event` function which was checking if the type was not a trade
and returning early, when in a larger universe of stocks the value
returned False 99% of the time.
Instead provide separate process functions specific to each type,
e.g. e.g. `process_trade` and `process_transaction` and route traffic to
those functions in tradesimulation.
For a universe of 160 stocks on both no-op algo and an algo that rebuys
its universe every day, saw about a 10% increase locally.
Also:
- Add process_benchmark to blotter since internal subclass relies on
logic on benchmark, this allows the internal process_trade to be a
`pass`.
- Add warning on unrecoginzed event types.
The risk containers that are actually used for reports use the
'cumulative' style container which has an index of days, not minutes.
The minute containers and copying of data etc. were causing an expanding
memory footprint.
The intraday_risk_metrics is being removed since the values are not
used; cumulative risk metrics with the last value updated to the latest
close has been used for some time.
Before the removal of intraday_risk_metrics, the position trackers
passing of benchmark returns to the cumulative risk metrics needs to no
longer depend on the calculations done by the intraday stats. So instead
use the all_benchmark_returns stored in the tracker directly.
on the number of per-tick update that occur since they were duplicated
per each PerformancePeriod. Also opens up the path to cythonizing the
entire object
Previously the class SerializeableZiplineObject was used to
house basic __setstate__ and __getstate__ methods. It wasn't
really doing much that was helpful, so it is now gone.