So that TALib is still available, but smooth out the ability to
run tests with some issues that bear investigating.
- Ignore MAVP during tests.
- Temporarily use a "regular" member instead of __doc__ string.
(TODO: look into using `type` to generate the class)
- During tests wait until a window exists.
In the previous implementation of batch transform it happened
that a window_length of `0` caused the transform to update on every
bar, for the time being that behavior should be retained,
though the new rolling implementation more correctly aligns to the
term of 'period' so a period of 1 would achieve the same effect.
When moving BatchTransform off of EventWindow as a base object,
the checking of window length was lost, restore that check using
the same function as EventWindow.
Add a test suite of dividend performance that ensures a holiday
is covered, needed because tests usually go over a random test range,
so holiday coverage isn't covered in basic test.
From @fawce.
Note, in a somewhat Catch-22 situation, the refactoring of
the simulation loop and streaming of minutely benchmarks enable
each other, since the benchmarks fall over because of doubled
date groupings, which is fixed by the change of the simulation loop,
but the simulation loop depends on using the benchmarks as a clock,
so pull the two changes in together, though the two changes do not
work independently of each other.
- Create different benchmark containers in performance
depending on emission rate.
- Add a minute close method which updates algorithm and
benchmark returns, and calculates the risk metrics
depending on those methods.
- Provide fake 0.0 values for annualized metrics like
sharpe, sortino, and information, until we figure out
how they should be treated in the context of minutely
calculation.
*NOTE* This does not fully work without the changes to the
simulation loop by @fawce
Eventually should to either return None or remove
progress completely, but in the meantime, return a
constant of 1.0 for progress of minute emissions.
Also, factor out the daily calculation into a property
instead of calculating during process.
Daily data should be using midnight as the timestamp,
ensure that test data created by data_gen use midnight, so that
upcoming implementations that rely on the timestamp will be compatible.
Instead of creating a set of perf messages for each event during minute
emission mode, only include the messages on the last event in the bar.
Should cut down on calculations/serialization as well, as work towards
doing more 'end of bar' logic for minute benchmarks.
Make adjustments for using Python built-in ElementTree instead of lxml
based lxml.
lxml was edited out during pulling in of memory friendly loading of
treasury curves, however some of the use of ETree was lxml specific.
Mea culpa.
The use of np.allclose introduced a severe performance penalty,
caused by the creation of two `np.array`s for each check.
Instead create and use a similar check which maintains tolerance
to floating point rounding, but operates only on scalars.
eigen vales, covariance, etc. are not calculated until the first
return is passed through, so initialize this values to None, so that
`repr` and its ilk work on a freshly created `RiskMetricsIterative`
object.
The bar timestamps for day start and finish, for NYSE traded stocks,
should be 9:31 AM EST to 4:00 PM EST, for a total of 390 minutes.
Fix starting at 9:30 AM and the creation of 391 bars.
Instead of creating a list of benchmarks in the risk module,
stream benchmarks through the system as events, starting from the
algorithm generator.
Works towards more easily setting arbritrary pricing data as
a a benchmark, as well as working towards live minutely benchmarks.
- Add transaction and order types
- Move TransactionSimulator from trading.py to tradesimulation.py
(only used by other members of the tradesimulation module)
- Make Transaction an independent event, like dividend
- Add Blotter class.
- Flatten the transaction events to be independent of trade bar events
- Make orders into events that reach performance (need to add
handling)
- Issue IDs to orders and tracking each transaction's order id.
- Make volume share slippage fill orders independently, rather than
aggregating them into a single transaction.
- Perf tracker holds orders, serializes them with transactions.
- Order state defined and maintained by order class.
- Minutely emission of orders based on last_modified date.
Also, fix double emission of performance results with the last minute.
Change the perf tracker unit tests so that it doesn't rely on an
'extra' event triggering emission.
Unlike daily, minute emission now emits at the end of the bar in
the PerformanceTracker.transform instead of waiting for the next event.
During minute emissions, it is still helpful to have a final daily
performance result, analogous to what would be the final packet in
a daily emitted backtest, so that all transactions, etc. are contained
in one place.
Prevent an extra performance result with the timestamp of the midnight of
the day from being emitted.
Fix by setting the `saved_dt` value with the dt of the first event,
before entering into the main performance loop, otherwise a performance
result with a midnight timestamp and data from just the first event is
emitted.
The `test_multi_source_as_input_no_start_end` test is designed
to test for a lack of simulation parameters, so make that they are
not passed.
Was unnoticed because sim_params passed as an arg are dropped.
The start and end of the simulation parameters should be 'normalized'
i.e. midnight timestamped.
However, the algorithm tests were using the timestamp of the
first and last trade, which were in market times,
i.e. 9:30 AM and 4:00 PM EST.
Fix passing the sim_params that is used to create the trade_history,
instead of having the sim_params inferred from the source.
(Also may want to consider fixing the logic that infers the date
range from the sources provided.)
Also, add a `num_days` option to `factory.create_simulation_parameters`
so that the a date range that covers the desired number of days is covered.
Since the default sim_params were covering a year, while the test only
supplies 4 values, causing an alignment issue with the record test,
since a years worth of results were returned, but there were only 4 events.
The cost value should always be a float.
The per share calculation shouldn't be changed dramatically by being
a float, (except for potential rounding errors), but change to so
that PerShare and PerTrade are aligned.
# Please enter the commit message for your changes. Lines starting
When the cost basis was set to an integer the division in the
calculation would floor down to the nearest integer.
Ensuring that the number is a float during PerTrade's init
will ensure that the calculation doesn't use integer division.
Do the conversion to float in init rather than calculate, so that
calling the builtin `float` is not added to any inner loops.
As currently implemented, progress doesn't currently make sense with
minutely results. Dropping the field from the results so should help
reduce some noise.
The intraday performance results were emitting all transactions
for the entire day up to that point, instead of the desired transaction
list for the current timestamp.
Add a `dt` parameter to the `to_dict` method of PerformancePeriod so
that the transactions are limited to a specific datetime.
When the parameter is `None`, a todays_performance object will
function as previously with returning all transactions for the day.
# Please enter the commit message for your changes. Lines starting
The indexing into performance results during the simulation loop fails
when emitting minutely since 'daily_perf' only exists on daily performance
results, not the minutely results.
Fix by making the key used to index into performance results depend
on the emission rate.
Intent is to both make the inputs to the treasury curve logic
more clear/explicit, as well as reducing the responsibilities
of the RiskMetrics classes.
Functions to move:
- search_day_distance
- get_treasury_rate
- choose_treasury
Also add new function:
- select_treasury_duration, split out of choose_treasury
So that calculations that leverage the range of the treasury_curves,
like `pd.Series.searchsorted` will not overshoot the 'end' of the
range we are calculating risk metrics.
The treasury_duration member in RiskMetrics is never used except
for in unit tests.
Remove the saving of treasury_duration in preparation for the
move of the choose_treasury method out of the RiskMetrics classes.
Down the line, if we do restore the sanving of treasury_duration,
choose_treasury can return a tuple that includes treasury_duration
instead of just returning the rate.
To make the risk metrics being calculated more clear, change the
naming convention that ratios have a '_risk' suffix.
Also, fixes typo in beta docstring.
Highlights:
- Benchmark updating now permits empty ranges.
(Fixes runtime crash when running immediately after Easter 2013.)
- Risk metrics
- Performance improvents from converting to numpy and pandas.
<@wesm, wesmckinn@gmail.com>
- Refactoring of risk metric calculation out of class structure.
On ranges with missing data from Yahoo, e.g.:
On 2013-04-2 the date range of April 2013-03-29 failed because
of the first day in the range being Good Friday, and the API not
yet updating for the Monday after.
Handle the 404 that is found by raising and warning that no
benchmark data was found, but continuing on.
In the test factory creation of returns, the date creation was using
a timedelta of one day instead of incrementing by trading days.
Working towards changing risk module behavior which would leverage
the trading day map, but tests fail because non-trading days are
created.
Remove `factory.create_returns`, moving uses of that function to us
`factory.create_returns_from_period`, since the number of days input
for `create_returns` was more difficult to use when specifying ranges
over arbirtray dates.
Move the risk metric definitions to functions at the module level
with defined parameters.
Both risk implementations call these functions, where the difference
between risk implementations is with which internal data they
send to the various risk metrics.
Metrics moved:
- Sharpe Ratio
- Sortino Ratio
- Information Ration
- Alpha
Following the lead of the RiskMetricsBatch conversion to use
more pandas and numpy.
Bringing the iterative and batch versions closer together as we
work towards folding them into one.
Handles the case when reword is called and the `commit --amend` invokes
the pre-commit hook, when there is no stash the `git stash pop -q`
in that case leaves the rebase in an odd state.
Fixes by only calling the stash pop if changes were saved.
So that the environments' exchange time is used without having to
specify it independently.
Also, moves uses of Delorean.shift for the exchange conversion inside
of environment to use the exchange_dt_to_utc method.
Wires up performance tracker so that when `emission_rate` is set
to `minute`, the performance packets are sent out every minute,
instead of once per day.
Please note, the performance packets that are generated are not
ready for prime time consumption, this patch is merely a step towards
hooking up the ability to inspect minute data.
Known issues:
- The packets do not currently include risk information.
Since we need to consider how this affects the denominators
of the risk calculations.
In preparation of changing how risk metrics are calculated,
this makes the checking of results more tolerant to floating point
rounding, since upcoming changes change the results by a neglible margin.
The pyandoc module throws an OSError of:
"No such file or directory",
when the underlying pandoc binary does not exist.
This error has caused confusion for numerous people during pip
installation.
pandoc is only needed on upload to PyPI to convert to ReST.
So, instead of doing a try/except on the `import pandoc` for all cases,
now checking whether or not 'upload' was invoked when calling setup.py,
so that only maintainers have to worry about installation of pandoc.
By only exercising the pandoc logic when
Converts the risk iterative and batch comparison tests to use
the trading environments next date, instead of just advancing by day,
so that the returns being passed into the RiskMetrics in the unit
test are using the same trading calendar as the internal checks for
trading days.
Fixes a case where empty return periods were being into
`calculate_period_returns`
Clearing the way for the pandas based optimization of the risk module.
So that Transaction object behavior is exercised, uses the Transaction
object in performance module tests instead of ndict.
Also, adds fields to the __init__ of Transaction, to make the
definition of the object more well defined.
This function is unused, and on the general path of moving testing
functions out of gens.utils
# Please enter the commit message for your changes. Lines starting
Slight refactoring of grouping the tracking variables in the
PerformanceTracker together.
So that it's easier to see which are config members and which are
members used to track internal state.