Compare commits

...
Author SHA1 Message Date
fredfortier d1e779b85e Refactoring exchanges 2017-08-26 14:31:09 -04:00
fredfortier 9bd966d627 Merged develop changes
# Conflicts:
#	catalyst/__main__.py
#	catalyst/utils/run_algo.py
#	catalyst/utils/run_algo_original.py
#	zipline/utils/run_algo.py
2017-08-26 14:09:59 -04:00
fredfortier eda8c8ce11 Fixes after rebasing to develop 2017-08-26 13:41:27 -04:00
fredfortier 816b936737 Modified the cli to take additional parameters 2017-08-24 12:42:45 -04:00
fredfortier c0455eca7c Bug fixes 2017-08-24 02:28:43 -04:00
fredfortier 8527866b48 Computing daily stats for analyze 2017-08-24 00:58:29 -04:00
Frederic Fortier 75385d034b Computing daily stats for analyze 2017-08-24 00:44:22 -04:00
Frederic Fortier 580c33c957 Improved daily performance tracking 2017-08-23 14:41:01 -04:00
Frederic Fortier c902949eb2 Improved daily performance tracking 2017-08-23 14:31:10 -04:00
Frederic Fortier a8763a589e Bug fixes 2017-08-23 00:09:57 -04:00
Frederic Fortier 05f1b0ae5e Bug fixes 2017-08-23 00:04:39 -04:00
Frederic Fortier a385732113 Bug fixes 2017-08-22 23:48:03 -04:00
Frederic Fortier 946954b308 Bug fixed in the sample algo 2017-08-22 15:33:42 -04:00
Frederic Fortier 8b81e66d57 Bug fixes and trying to cache minute data 2017-08-22 14:59:47 -04:00
Frederic Fortier a5ca8d0f15 Housekeeping and documentation 2017-08-21 15:03:50 -04:00
Frederic Fortier 069639a325 Bug fixes and housekeeping 2017-08-21 14:30:55 -04:00
Frederic Fortier 346780c3f0 Bug fixes 2017-08-21 00:16:34 -04:00
Frederic Fortier 886b2debe9 Saving portfolio and stats to keep state between runs 2017-08-20 18:50:38 -04:00
Frederic Fortier 4d6c0ca699 Using files for exchange connection and symbol map 2017-08-20 17:35:09 -04:00
Frederic Fortier 7fe2e5c929 Using files for exchange connection and symbol map 2017-08-20 17:34:04 -04:00
Frederic Fortier d3b06a083c Polishing the algorithm 2017-08-20 15:38:59 -04:00
Frederic Fortier ef40339058 Polishing error handling 2017-08-20 14:04:37 -04:00
Frederic Fortier 1a98ea1639 Trying to improve performance tracking 2017-08-20 01:40:11 -04:00
Frederic Fortier 9f96d5fbe4 Error handling improvements 2017-08-19 23:47:13 -04:00
Frederic Fortier 94bb99da3b Error handling improvements 2017-08-19 23:45:33 -04:00
Frederic Fortier f66ef99202 Performance tracking improvements 2017-08-19 23:13:04 -04:00
Frederic Fortier 2c9c4b0d05 Error handling improvements 2017-08-19 19:25:06 -04:00
Frederic Fortier 1045dcd5bd Error handling improvements 2017-08-19 18:36:52 -04:00
Frederic Fortier e497fe76d7 Error handling improvements 2017-08-19 18:34:36 -04:00
Frederic Fortier 1fe8ee6577 Implemented get_history_window for exchange and bitfinex 2017-08-19 18:20:40 -04:00
Frederic Fortier 14047fde15 Working on history implementation and improving error handling. 2017-08-19 15:51:57 -04:00
Frederic Fortier 30e15a7b8b Improved performance tracking. 2017-08-18 16:02:08 -04:00
Frederic Fortier 37a07e03e5 Minor fixes 2017-08-18 02:03:00 -04:00
Frederic Fortier 51cda7b2d4 Implemented portfolio stats 2017-08-17 23:53:49 -04:00
Frederic Fortier 6f591305e3 Improved documentation formatting 2017-08-17 18:30:01 -04:00
Frederic Fortier d48373a75a Expanded on documentation 2017-08-17 16:13:04 -04:00
Frederic Fortier f7db6471ca Minor adjustments and draft documentation 2017-08-17 15:31:44 -04:00
Frederic Fortier 2c122f6356 First version which runs end-to-end. 2017-08-17 02:00:43 -04:00
Frederic Fortier 3949364d31 First version which runs end-to-end. 2017-08-17 01:40:03 -04:00
Frederic Fortier 55f898562c First version which runs end-to-end. 2017-08-17 01:20:46 -04:00
Frederic Fortier fade9758a8 Trying to run a live algo 2017-08-15 01:37:35 -04:00
Frederic Fortier 270175b6c4 Housekeeping 2017-08-14 20:12:01 -04:00
Frederic Fortier 4f1927bc34 Polishing live trading components 2017-08-14 18:37:40 -04:00
Frederic Fortier 05ae879c4f Got trading algorithm and related pieces 2017-08-14 18:37:40 -04:00
Frederic Fortier fcff8c7438 Implemented order operations 2017-08-14 18:37:40 -04:00
Frederic Fortier 383370f9d8 Code documentation and cleanup 2017-08-14 18:37:40 -04:00
Frederic Fortier 0b16cce71e Adding the first exchange (Bitfinex) and unit testing 2017-08-14 18:37:40 -04:00
Victor Grau Serrat 43e669d838 Merge branch 'rc-0.1.dev7' 2017-08-14 14:57:29 -04:00
VictorandGitHub 92139dd500 Merge pull request #24 from rterbush/tz-localize
Normalize timestamps before comparison.
2017-08-14 14:42:19 -04:00
Victor Grau Serrat e22b2df45f fix issue #16 of empty files in /var/tmp; treasury data start 19990 2017-08-14 06:22:55 -04:00
Victor Grau Serrat 00f2063e21 OPEN cal start=2015-03-01, minor fixes for rc-0.1.dev7 2017-08-09 12:49:53 +02:00
Victor Grau Serrat 1f272f9ff8 asset_filter fix, revert old bundle paths, BaseBundle exception fix 2017-08-08 21:13:59 +02:00
VictorandGitHub 10169734d2 Updated README 2017-08-02 01:44:47 +02:00
Randy Terbush 141e414466 Normalize timestamps before comparison. 2017-08-01 15:44:31 -06:00
Conner Fromknecht 3df274431e WIP: Integration of generic bundle and five minute bars 2017-07-21 04:10:58 -07:00
Conner Fromknecht e28459b19f Initial work on quandl bundle 2017-07-21 04:10:58 -07:00
VictorandGitHub 7cf06909ce Update README.rst 2017-07-13 22:58:38 -04:00
Conner Fromknecht de8777d1c8 Further documentation of BaseBundle class and UI improvements 2017-07-13 16:12:32 -07:00
Conner Fromknecht 24141964bf CLI UI improvements
* Customzed progressbar format and display information
 * Added new bar to BaseBundle and DailyBarWriter
2017-07-13 16:12:32 -07:00
Conner Fromknecht cabea94973 WIP: Generic Data Bundles
* Split up inheritance structure of Bundle classes
2017-07-13 16:12:32 -07:00
Conner Fromknecht e8e2346c60 WIP: Five Minute bars and FiveMinuteSimulationClock 2017-07-13 16:12:32 -07:00
Conner Fromknecht 6e47f704b4 WIP: abstract bundle class for generalizing data curation
Started PoloniexBundle to adapt current ingestion logic to new structure
2017-07-13 16:12:32 -07:00
Guy ZyskindandGitHub dd97526489 Merge pull request #4 from enigmampc/polo-curate-fixes
Fixes formatting errors in catalyst/curate/poloniex.py
2017-07-10 22:42:44 -07:00
Conner Fromknecht 6b4209e038 Indentation fixes 2017-07-10 20:11:45 -07:00
Conner Fromknecht 6f79f8b9b8 Fixes formatting errors in catalyst/curate/poloniex.py 2017-07-10 20:01:04 -07:00
Conner Fromknecht 22ad375a52 Added uninitialized time import to fix uncached benchmark fetching 2017-07-07 02:23:19 -07:00
Conner FromknechtandGitHub 07fb239d11 Update README.rst 2017-07-06 15:16:00 -07:00
Conner Fromknecht c4e53a7ceb Removed use of global variables from example strategies 2017-07-06 15:11:05 -07:00
Conner Fromknecht c4bbbb4732 Converted OHLCV columns to use uint64. Default tick size now 1/1000th of a coin 2017-07-06 15:06:35 -07:00
Conner FromknechtandGitHub 7576979003 Update README.rst 2017-07-03 16:29:41 -07:00
Conner FromknechtandGitHub ac70fb97d2 Update README.rst 2017-07-03 10:27:33 -07:00
Conner Fromknecht 52f68fbea6 Notes on default denomination, 1/10-th of full coin 2017-07-03 09:27:19 -07:00
Conner Fromknecht cbaccda564 Adjust examples plots to display price of full coin 2017-07-03 00:50:38 -07:00
Conner Fromknecht 0a0c96ba0c Update README.rst
Shell command for amending matplotlibrc, inspired by pyfolio
2017-07-01 18:27:17 -07:00
Conner Fromknecht 671f6febfe Updated example strategies 2017-07-01 18:27:17 -07:00
Conner Fromknecht b4e0c6d2bb Update README.rst 2017-07-01 18:27:16 -07:00
Conner Fromknecht e3b7601f37 Convert Timestamp to UNIX time before fetching benchmark 2017-07-01 18:27:16 -07:00
Conner Fromknecht d2d297d348 Expose poloniex data curation methods to load benchmark dynamically 2017-07-01 18:27:16 -07:00
Conner Fromknecht 8134b96ac3 Update README.rst and examples
Never stop hodling
2017-07-01 18:27:16 -07:00
Conner Fromknecht 4a62f5f366 Update README.rst 2017-07-01 18:27:16 -07:00
Conner Fromknecht 0989919044 Update README.rst 2017-07-01 18:27:16 -07:00
Conner Fromknecht 21dcbccbe3 Fixed bundle imports 2017-07-01 18:27:16 -07:00
Conner Fromknecht cd8af67068 Update poloniex bundle URL 2017-07-01 18:27:16 -07:00
Conner Fromknecht fb2afaff36 Changed package name to enigma-catalyst 2017-07-01 18:27:16 -07:00
Conner Fromknecht 5ab98dbfd9 Remove get_calendar print 2017-07-01 18:27:16 -07:00
Conner Fromknecht b55458f9c5 Updated examples 2017-07-01 18:27:16 -07:00
Conner Fromknecht 06e672a75e Ingest poloniex data from remote tar 2017-07-01 18:27:15 -07:00
Conner Fromknecht 84afcf68ef Moved bundle download methods into catalyst/data/bundles/core 2017-07-01 18:27:15 -07:00
Conner Fromknecht 4667f31b20 Improved Buy and Hodl example 2017-07-01 18:27:15 -07:00
Conner Fromknecht 18228dcd8e Update README.rst 2017-07-01 18:27:15 -07:00
Conner Fromknecht bb17c171e5 General improvements 2017-07-01 18:26:57 -07:00
Conner Fromknecht 0982998288 Initial BcolzFiveMinuteBarWriter/Reader 2017-06-23 18:49:19 -07:00
Conner Fromknecht 0f96bbb182 USDT_BTC benchmark
This commit:
 * Adds a crypto_benchmark that can create benchmarks for symbols found on POLO
 * Changes default trading calendars to OPEN
 * Properly computes daily bar data from five minute POLO bars
 * Allows trading of one hundredth of a coin, later we plan to integrate per the
   ratio of a full coin to its base denomination.
2017-06-23 18:44:45 -07:00
Conner Fromknecht de839654fd Untold improvements 2017-06-22 20:50:07 -07:00
Conner Fromknecht daeef1759e Merge branch 'master' of https://github.com/enigmampc/catalyst 2017-06-21 11:43:52 -07:00
Conner Fromknecht 05462dd6e2 Dual moving average for USDT_BTC 2017-06-21 11:41:11 -07:00
Conner Fromknecht bb9bf3bc9f Dual moving average for USDT_BTC 2017-06-21 10:59:20 -07:00
Conner Fromknecht 53d1c7d7c3 Changed default bundle to poloniex and new crypto examples 2017-06-20 17:23:21 -07:00
Conner Fromknecht d509dfb9a1 Working crypto data on NYSE calendar 2017-06-20 15:40:37 -07:00
Conner Fromknecht cd3d996892 NYSE -> OPEN calendar for (most) default calendars
* Added extra bundle parameters for catalyst/poloniex bundles
2017-06-20 14:18:15 -07:00
Victor Grau Serrat 3b6a293019 WIP: Poloniex bundle 2017-06-20 16:37:04 -04:00
Victor Grau Serrat a0da21e6ea WIP - curator: switch to requests, exception handling, dynamic currency list 2017-06-20 00:42:24 -04:00
Conner Fromknecht 2b8b14bb9b Run curator 2017-06-19 14:43:10 -07:00
Conner Fromknecht 2770648acb Fixed catalyst tests except example tests 2017-06-19 14:43:10 -07:00
Guy ZyskindandConner Fromknecht 0ff32b38d7 pricing data 2017-06-19 14:43:10 -07:00
Conner Fromknecht a38a35d664 Changed zipline -> catalyst import paths
* Updated cython build scripts
 * Updated setup.py to to install catalyst package
 * Updated momentum example to use catalyst package
 * catalyst executable now supports loading pipelines from multiple bundles
2017-06-19 14:43:10 -07:00
Conner Fromknecht f6ceeb8be1 Crypto integration + multiple pipeline bundles 2017-06-19 14:43:10 -07:00
Richard Frank 753004647b DEV: Pin configparser version
It's a recent (to zipline) requirement of flake8.
2017-06-08 17:33:15 -04:00
Scott SandersonandGitHub 0fa6c37b68 Merge pull request #1834 from quantopian/multiple-output-factor-window-safe
ENH: Match window_safe status of multi output factor with factor
2017-06-08 08:36:26 -07:00
Scott Sanderson 78c2404e55 TEST: Add test for window_safe propagation. 2017-06-08 10:59:56 -04:00
Ana Ruelas c8c626e15a ENH: Match window_safe status of multi output factor with factor 2017-06-08 10:19:04 -04:00
swacadandFreddie Vargus 2590afc6e8 DOC: Add development guide .rst 2017-06-07 21:50:19 -04:00
Scott SandersonandGitHub 885698d50b Merge pull request #1833 from quantopian/labelarray-map
Add support for relabeling classifiers.
2017-06-07 17:57:18 -07:00
Scott Sanderson ec2ec49914 MAINT: Make _sortable_sentinel a singleton. 2017-06-07 20:17:58 -04:00
Scott Sanderson 609ae752d0 DOC: Fix typo in docstring. 2017-06-07 18:22:30 -04:00
Scott Sanderson 8a042937d9 TST: Add test for missing values in relabel. 2017-06-07 18:21:13 -04:00
Scott Sanderson cbe52cea88 BUG: Fix NoneType comparisons in PY3. 2017-06-07 18:21:03 -04:00
Scott Sanderson e49f4c6149 ENH: Improve error message on bad return. 2017-06-07 17:07:19 -04:00
David MichalowiczandGitHub 011915d4fc Merge pull request #1822 from quantopian/var-and-cvar
Add portfolio weights method to algorithms
2017-06-07 16:35:04 -04:00
Andrew DanielsandGitHub b5e01d99ef Merge pull request #1619 from quantopian/end-date-default-int64-max
MAINT: Define default end_date in assets.db as max int64, for clarity
2017-06-07 15:55:27 -04:00
David Michalowicz 49a7b78b2e Fix weights calculation to use portfolio value as denominator 2017-06-07 15:46:45 -04:00
Scott Sanderson ad10349992 TEST: Test map returning None. 2017-06-07 15:28:15 -04:00
Scott Sanderson a579485825 MAINT: s/NotImplementedError/TypeError. 2017-06-07 15:23:27 -04:00
Joe JevnikandJoe Jevnik e47a21318c BUG: fix assert_equal for tuple-keyed dictionaries 2017-06-07 14:50:13 -04:00
Scott Sanderson cfe4df8f2b TEST: Test map ignores missing with None. 2017-06-07 14:16:17 -04:00
Andrew Daniels d0544a6581 MAINT: Define default end_date in assets.db as max int64, for clarity 2017-06-07 14:08:55 -04:00
Scott Sanderson e995e6f2ed ENH: Add relabel method to string classifiers.
- Adds a `map` method to `LabelArray` that maps a unary function over
  the categories of a LabelArray, shrinking the underyling codes if
  possible.

- Adds a new `.relabel` method to string-dtype classifiers that maps a
  unary function over the unique elements of the underlying LabelArray.
  This is useful for things like cleaning noisy label data.
2017-06-07 13:14:12 -04:00
David Michalowicz 94b1d5a40e ENH: Add method for computing current portfolio weights 2017-06-07 13:13:14 -04:00
Scott Sanderson 8b17b7d4b3 MAINT: Add validator to validate_column.
Who validates the validators?
2017-06-07 11:50:37 -04:00
Scott Sanderson ba590266c9 MAINT: Simplify ArrayPredicate.
Just use `params` instead of custom `_init` and `_static_identity`.
2017-06-07 11:49:37 -04:00
Freddie VargusandFreddie Vargus 731e3a8678 TST: Updated modified time of market data in test_examples 2017-06-07 11:00:55 -04:00
Ana RuelasandGitHub 440ff4205b Merge pull request #1826 from quantopian/add-engine-docs
Add engine docs
2017-06-06 11:21:57 -04:00
Ana Ruelas 73d66216dc DOC: Include pipeline Term in documentations 2017-06-05 16:11:19 -04:00
Ana Ruelas 1051ef1eb8 DOC: Include all Factor methods in documentation 2017-06-05 16:10:47 -04:00
Ana Ruelas cc867dbdfe DOC: Include PipelineEngine in documentation 2017-06-05 16:09:36 -04:00
Ana Ruelas 090ce3b256 DOC: Removed non-existent classes from docs 2017-06-05 16:08:21 -04:00
Ana Ruelas 3ba34aa755 DOC: Change docstrings to make documentation easier to read 2017-06-05 16:01:33 -04:00
Ana Ruelas 11c0782e9a DOC: Create built in factors subheading, organize them alphabetically 2017-06-05 16:00:09 -04:00
Ana Ruelas e55a6078d6 DOC: Fix invalid sphinx sections 2017-06-05 15:52:57 -04:00
Freddie VargusandGitHub a40e5d932c Merge pull request #1812 from quantopian/google-finance-for-benchmarking
BUG/MAINT: Switch over to Google for benchmarking
2017-06-05 12:09:55 -04:00
Freddie Vargus c0c67340fe MAINT: Skip more rows to match change in treasury data format
I'm not sure what the raw csv pulled from the federal reserve looked like before, but when trying to download fresh treasure data (data not stored in `./zipline`), there is an error that says "Time Period not in list". After checking the raw csv now, it looks like there are 5 header rows rather than just 1, so skipping those rows removes that error.
2017-06-05 11:44:01 -04:00
Ana RuelasandGitHub e6fe3a0e7d Merge pull request #1811 from quantopian/run-chunked-pipeline
Run chunked pipeline
2017-06-02 17:29:15 -04:00
Ana Ruelas ad3c72a8fb ENH: Use context manager to suppress nan-categorical warning 2017-06-02 16:48:26 -04:00
Ana Ruelas ff1c673a9d ENH: Include sharedoc function 2017-06-02 16:48:26 -04:00
Ana Ruelas 2d56d253fa ENH: Add run_chunked_pipeline method to PipelineEngine 2017-06-02 16:48:09 -04:00
Ana Ruelas 69b632db37 ENH: Add function for running pipelines in chunks 2017-06-02 16:47:55 -04:00
Ana Ruelas c59518bbeb ENH: Add function to concatenate list of dataframes with categoricals
STY: Alphabetized import list
2017-06-02 16:47:37 -04:00
Miguel Sánchez de León PequeandAna Ruelas a2fbb9ee7f Add missing Python 3.5 references (now supported)
Add this version to the Conda build matrix and to the setup.py file.
2017-06-02 16:47:36 -04:00
Freddie Vargus 26175180dc TST: Change start date to fit benchmark start date 2017-06-01 23:35:11 -04:00
Freddie Vargus d9d41e3bb7 TST: Sort test examples to debug more easily 2017-06-01 23:35:11 -04:00
Freddie Vargus 5c6fe19e8e BUG/MAINT: Switch over to Google for benchmarking
MAINT: Remove mentions of Yahoo & ^GSPC

MAINT: Fill in missing dates

MAINT/BLD: Rebuild example data to match new benchmark
2017-06-01 23:35:10 -04:00
Freddie VargusandGitHub 1ab0cd7113 Merge pull request #1809 from Peque/py35
BLD: Add some missing Python 3.5 references
2017-05-28 21:37:14 -04:00
Freddie VargusandFreddie Vargus 0a672c7343 MAINT: Remove label=omit from treasury link
MAINT: Switch to https
2017-05-26 13:57:51 -04:00
Eddie HebertandGitHub 912165da06 MAINT: Remove environment as an argument to benchmark source. (#1816)
MAINT: Remove environment as an argument to benchmark source.

To allow the BenchmarkSource class to be more easily used in contexts other than
a TradingAlgorithm, remove the TradingEnvironment as an argument to the
benchmark source.

Instead:
- Pass a benchmark Asset, instead of a bencmark sid; so that the asset_finder
does not need to be passed to the benchmark source.
- Pass the pre-calculated benchmark_returns instead of an env,
which contains the benchmark_returns; a consumer can let the benchmark_returns
stay as the default of `None` when using an asset.

We may want to further refactor and make two different classes, instead of
relying on a combination of existence/non-existence of benchmark_asset and
benchmark_returns. That refactoring should be easier to do with this change.
2017-05-25 16:11:25 -04:00
Samantha KlonarisandGitHub 77f1013d49 Merge pull request #1815 from quantopian/get-array-benchmark-source
ENH: Add get_range to BenchmarkSource
2017-05-25 10:51:48 -04:00
Samantha Klonaris 0d3ba78177 ENH: Add get_range to BenchmarkSource 2017-05-25 10:14:40 -04:00
Freddie VargusandRichard Frank b0b60391f0 BLD: Modify conda label for Travis CI (#1814)
* BLD: Modify conda label for Travis CI

We've been unnecessarily building packages that are already in the ci channel because conda build isn't respecting the full URL for that channel when using --skip-existing.  We updated it to be just the name of the channel.
2017-05-24 22:37:03 -04:00
Freddie VargusandFreddie Vargus fa76c29334 BLD: Swap conda build args to check CI label/channel first
BLD: Change url to just channel/label path
2017-05-24 19:44:37 -04:00
David MichalowiczandGitHub 167d76afd3 Merge pull request #1788 from quantopian/rounding-cutoff-2
Do not explicitly round asset prices
2017-05-24 11:30:00 -04:00
dmichalowicz c9351d4c18 BUG: Some futures prices need more precision when rounding 2017-05-24 08:18:52 -04:00
Freddie VargusandGitHub 595e30db8e Merge pull request #1806 from ChrisPappalardo/pycon2017_sprints_docker
DOC: Add instructions for common Docker build failures
2017-05-23 17:05:12 -07:00
Andrew LiangandGitHub 8579ce7b1a Merge pull request #1782 from quantopian/no_slippage_comparison
MAINT: Remove __eq__ implementation from slippage
2017-05-23 15:39:36 -04:00
capandChris Pappalardo c9bbc23bc5 updated dockerfiles with instructions for dealing with common build failures and updated base image from python 2.7 to 3.5 2017-05-23 09:57:25 -07:00
Miguel Sánchez de León Peque e5ef118f3b Add missing Python 3.5 references (now supported)
Add this version to the Conda build matrix and to the setup.py file.
2017-05-23 09:39:21 +02:00
Andrew Liang 8d5a2dd0ce MAINT: Remove __eq__ implementation from slippage 2017-05-22 23:00:24 -04:00
Scott SandersonandGitHub 8905051736 Merge pull request #1802 from Peque/calendar_bug
Fix bug in TradingCalendar initialization
2017-05-22 16:47:51 -07:00
Freddie VargusandGitHub 7412aa54f5 Merge pull request #1701 from quantopian/py35-support
BLD: Update CI files for py35
2017-05-22 14:48:35 -07:00
Freddie VargusandFreddie Vargus 268b1cb6ad DOC: Update beginner tutorial 2017-05-22 12:56:10 -07:00
Miguel Sánchez de León Peque 35143c3e1b Fix bug in TradingCalendar initialization
A TypeError exception was raised with message "Cannot join tz-naive with
tz-aware DatetimeIndex". Removing old unnecessary workaround in
`holidays_at_time` function (Pandas already fixed that before 0.18)
fixes this issue.
2017-05-22 13:27:01 +02:00
Freddie VargusandFreddie Vargus d6034682f1 MAINT: Remove .bumpversion.cfg because we haven't used it lately 2017-05-21 11:32:08 -07:00
Ana RuelasandGitHub dcae4bf8a3 Merge pull request #1798 from quantopian/with-equity-pipeline-engine
With equity pipeline engine
2017-05-19 10:48:15 -04:00
Ana Ruelas a72d7a7b34 ENH: Add WithEquityPricingPipelineEngine test fixture 2017-05-19 10:04:30 -04:00
Scott SandersonandGitHub a3edae9845 Merge pull request #1794 from Peque/peque
Fix docstring in TradingEnvironment class
2017-05-19 05:52:56 -07:00
Richard FrankandGitHub 9f128cbde1 Merge pull request #1793 from quantopian/tests-without-yahoo
TST: Don't require downloading of data for tests
2017-05-18 13:27:08 -04:00
Richard Frank ec396bd1ea TST: Use testing market data with run_algorithm
so env doesn't need to download it
2017-05-18 12:54:06 -04:00
Richard Frank 0f6dbcef3c TST: Use fixture's data with tmp_trading_env
instead of env needing to download it
2017-05-18 12:54:05 -04:00
Richard Frank c5b3ceecc1 TST: Use fixture's trading env for FakeDataPortal or TradingAlgo
to avoid a new trading env needing to download data unnecessarily
2017-05-18 11:55:48 -04:00
Miguel Sánchez de León Peque 3b3854c3bf Fix docstring in TradingEnvironment class 2017-05-17 18:42:36 +02:00
Freddie Vargus 8cc97d75b5 BLD: Update CI files for py35
BLD: Move setuptools_scm recipe earlier

in build process. We order alphabetically.

BLD: Update to newest Cython version

BLD: Update version of matplotlib

BLD: Pin matplotlib dependency
2017-05-16 15:33:27 -04:00
Scott SandersonandGitHub dde4974705 Merge pull request #1791 from quantopian/cleanup-latest-flake8
MAINT/STY: Upgrade flake8 and fix new failures.
2017-05-15 11:39:51 -07:00
Scott Sanderson 616f6e5e5d MAINT/STY: Upgrade flake8 and fix new failures. 2017-05-15 11:45:04 -04:00
David MichalowiczandGitHub c70244fe7f Merge pull request #1789 from quantopian/more-commission-cleanup
Refactor commission model class hierarchies
2017-05-12 13:55:39 -04:00
David Michalowicz 5678d2d37b MAINT: Refactor commission model class hierarchies 2017-05-12 12:31:36 -04:00
Scott SandersonandGitHub 705044830b Merge pull request #1750 from quantopian/remove-batch-otp
MAINT: batch_order_target_percent -> batch_market_order.
2017-05-11 11:30:35 -07:00
Scott Sanderson d39f012198 MAINT: Mark .ipynb files as binary.
Makes `git grep` not print the binary content of png files.
2017-05-09 13:52:57 -04:00
Scott Sanderson 86fa28f9e8 MAINT: batch_order_target_percent -> batch_market_order.
The only downstream contex that was using batch_order_target_percent
already had all necessary prices, so calling batch_order_target_percent
was wasteful.
2017-05-09 13:52:57 -04:00
David MichalowiczandGitHub 281a17c592 Merge pull request #1767 from quantopian/no-slippage-history
More futures slippage cleanup
2017-05-09 13:17:28 -04:00
dmichalowicz 5327fc9a05 MAINT: Various futures slippage model fixes and cleanup
- Handle history lookback error before start date
- Adjust default futures slippage volume limit
- Allow subclassing EquitySlippageModel and FutureSlippageModel together.
2017-05-09 11:47:55 -04:00
Richard Frank b246f6a03b SEC: Rotate secure vars for anaconda tokens 2017-05-09 11:28:55 -04:00
Andrew DanielsandGitHub 072466e08c Merge pull request #1785 from quantopian/reindex-reader-get-value
Fixes equity history calls on the futures calendar
2017-05-09 10:33:58 -04:00
Andrew Daniels a416662a9c MAINT: Pass data_frequency to get_history_window
This allows us to remove the check for whether the provided dt had a
time of midnight, which was a flimsy way to infer if the data frequency
was 'daily'. Besides the explicit check being preferable, this method
was broken on the futures calendar, since midnight is a valid market
minute.
2017-05-09 09:34:39 -04:00
Andrew Daniels 43e0545856 BUG: Fix _handle_minute_history_out_of_bounds for future calendar
Need to use minute_to_session_label to retrieve the proper session.
2017-05-09 09:34:38 -04:00
Andrew Daniels bffb4bfea5 TST: Adds MinuteEquityHistoryFuturesCalendarTestCase
Added as a subclass of MinuteEquityHistoryTestCase, where the primary
calendar is 'us_futures'.

Notes on modifications to MinuteEquityHistoryTestCase:

- To work on generic calendars, many tests now use set minutes for
  window start and end, and check the values on active equity minutes.
- test_minute_regular should test against active equity minutes
- Adapts test_minute_midnight to work with futures calendar
  - Use a method of getting the last open minute that works with
    calendars that are open at midnight
  - Test against Sunday at midnight, since the real intention of this
    test is to check that given a non-open minute, we fall back to the
    last open minute.
2017-05-09 09:34:38 -04:00
Andrew Daniels 78ae3474ad TST: Adds DailyEquityHistoryOnFuturesCalendarTestCase
Added as a minimal subclass of DailyEquityHistoryTestCase, swapping out
just the primary calendar. This requires significant modifications to
DailyEquityHistoryTestCase, to allow for a generic primary calendar.
2017-05-09 09:34:38 -04:00
Andrew Daniels da63a117e0 MAINT: Modify ReindexBarReader.get_value to handle missing data
Instead of raising an exception, return 0.0 for volume, and nan for
everything else.
2017-05-09 09:34:37 -04:00
Freddie VargusandGitHub 18ee06f0d4 Merge pull request #1746 from quantopian/update-transaction-repr
MAINT: Add better repr for transactions
2017-05-08 14:54:24 -04:00
Richard FrankandGitHub d733605327 Merge pull request #1783 from quantopian/slippage-cleanup
Slippage cleanup
2017-05-05 14:36:25 -04:00
Richard Frank 035311213e MAINT: allowed_asset_types is already defined in the base class 2017-05-05 14:09:02 -04:00
Richard Frank 56a993bfc6 BUG: Fixed abstractness of MarketImpactBase 2017-05-05 14:09:02 -04:00
Richard Frank a1d055abb1 MAINT: process_order is a method
and call super's __init__ to set up base state
2017-05-05 14:09:01 -04:00
Andrew DanielsandGitHub 07561469bc Merge pull request #1780 from quantopian/include-diff-in-daily-bars-assertion
MAINT: Display diff if input to daily bar writer has gaps/extra bars
2017-05-04 10:48:08 -04:00
Andrew Daniels 560ff3cacf MAINT: Display diff if input to daily bar writer has gaps/extra bars 2017-05-04 10:19:09 -04:00
Andrew DanielsandGitHub 52667b4a90 MAINT: Handle gaps in input to daily bars writer (#1778)
Previously, a dataframe passed into BcolzDailyBarWriter.write that was
missing an expected session between its first and last sessions would be
written incorrectly. Upon converting the dataframe to a ctable, the
values for all days following the gap would be shifted backwards, and
nans would be shifted in at the end.

This commit handles the issue by asserting that the number of rows in
the input table matches the number of sessions in the calendar between
the table's first and last sessions.

Also fixes a test that was mistakenly using minutes_in_range where it
should have been using sessions_in_range (uncovered by this change).
2017-05-03 20:49:22 -04:00
David MichalowiczandGitHub f0e100bcf3 Merge pull request #1779 from quantopian/silver-chains
Gold/Silver futures contracts only trade certain months
2017-05-03 17:18:56 -04:00
dmichalowicz cb3926f81c BUG: Gold and silver futures contracts only trade certain months 2017-05-03 16:34:01 -04:00
Freddie Vargus 9095b241f2 MAINT: Add better repr for transactions
Flake8
2017-04-28 11:13:40 -04:00
David MichalowiczandGitHub c0123b9caa Merge pull request #1770 from quantopian/zero-transaction-volume
Futures slippage model could have zero transaction volume
2017-04-26 13:59:33 -04:00
dmichalowicz 3ff281079a BUG: Futures slippage model could have zero transaction volume 2017-04-26 13:35:00 -04:00
Jean BredecheandGitHub 06d8ddc3cc Merge pull request #1769 from quantopian/py3-warnings
BUG: Python3 compatibility.
2017-04-26 10:46:34 -04:00
Jean Bredeche 04cf61d03d BUG: Python3 compatibility. 2017-04-26 10:47:27 -04:00
Jean BredecheandGitHub a11574c942 Merge pull request #1768 from quantopian/shim-portfolio-access-by-int
BUG: Add backwards compatibility for position lookup by int.
2017-04-26 10:13:16 -04:00
Jean Bredeche dead9651b2 BUG: Add backwards compatibility for position lookup by int. 2017-04-26 09:55:05 -04:00
Scott SandersonandGitHub e3a50dee8f Merge pull request #1764 from quantopian/fix-docstring-typo2
DOC: Close backticks in docstring.
2017-04-25 22:52:28 -04:00
Scott Sanderson f7f17af2d8 DOC: Close backticks in docstring. 2017-04-25 22:32:11 -04:00
David MichalowiczandGitHub b77d5ae6fb Merge pull request #1763 from quantopian/slippage-allowed-types
Don't require custom models to define allowed types
2017-04-25 19:40:41 -04:00
dmichalowicz ec7cba2e31 API: Don't require custom models to define allowed types 2017-04-25 18:44:31 -04:00
David MichalowiczandGitHub 0782e402d3 Merge pull request #1748 from quantopian/slippage-futures-api
Add slippage and commission models for futures
2017-04-25 17:55:16 -04:00
dmichalowicz fa0594555c API: Add slippage and commission models for futures 2017-04-25 17:29:41 -04:00
Andrew DanielsandGitHub 9effe84c8e Merge pull request #1762 from quantopian/quarterly-currency-futures
MAINT: Use a quarterly cycle for JY, CD, AD, and BP continuous futures
2017-04-25 15:52:56 -04:00
Andrew Daniels a1d30c94ee MAINT: Use March quarterly cycle for JY, CD, AD, & BP continuous futures
The March, June, September, and December contracts for these futures
contain most of the trading activity, so we exclude the other more
sparsely traded contracts from the chain.
2017-04-25 15:31:33 -04:00
Jean BredecheandGitHub 362f2c2f7a Merge pull request #1761 from quantopian/futures-cashflow-bugfix
BUG: use isinstance
2017-04-24 17:06:34 -04:00
Jean Bredeche 278d2f6b2a BUG: use isinstance 2017-04-24 17:06:26 -04:00
Jean BredecheandGitHub 7ba070f640 Merge pull request #1757 from quantopian/futures-commissions
Assets everywhere ... and a futures fix.
2017-04-24 16:31:57 -04:00
Jean Bredeche 7196e1e498 MAINT: PR feedback. 2017-04-24 15:41:23 -04:00
Jean Bredeche 5b8b2f68bc BUG: Blotter should process as many splits as it can 2017-04-24 15:41:23 -04:00
Jean Bredeche 825866948b BUG: get_splits should return empty list, not empty dict 2017-04-24 15:41:23 -04:00
Jean Bredeche fe84ff3582 REF: Remove assetfinder from PerformancePeriod 2017-04-24 15:41:22 -04:00
Jean Bredeche 0b4b058065 REF: Remove asset_finder and multipliers from PositionTracker 2017-04-24 15:41:22 -04:00
Jean Bredeche b7b8c46d74 REF: Blotter no longer needs AssetFinder 2017-04-24 15:41:21 -04:00
Jean Bredeche 483012ccf6 REF: Make dataportal emit splits that hold Assets, not sids 2017-04-24 15:41:21 -04:00
Jean Bredeche 450690801a BUG: Position cost basis was calculated incorrectly for Futures
For futures, we need to divide the position’s commission by the
contract size to get a per-unit commission in order to properly update
the position’s cost basis.
2017-04-24 15:41:20 -04:00
Jean Bredeche 8d275d8d83 REF: Explicitly use Assets in Position, Order, Transaction
(Instead of `sid`, which were already usually assets)

Perf packets are unchanged and still emit `sid`: int
2017-04-24 15:41:13 -04:00
Jean BredecheandGitHub 21976dd651 Merge pull request #1760 from quantopian/constant-futures
TST: New fixture for constant futures data
2017-04-24 14:33:47 -04:00
Jean Bredeche e0060f61e8 TST: New fixture for constant futures data 2017-04-24 14:15:26 -04:00
David MichalowiczandGitHub 1d1c244e84 Merge pull request #1755 from quantopian/schedule-function-calendar
Add calendar factory for the schedule_function API
2017-04-24 10:07:30 -04:00
dmichalowicz 2f33ddb023 API: Add factory for calendars 2017-04-24 09:37:32 -04:00
David MichalowiczandGitHub cd91d518bb Merge pull request #1754 from quantopian/premature-continuous-futures-2
Allow gaps between auto close and start date
2017-04-21 16:34:53 -04:00
dmichalowicz 0ec8841ea0 BUG: Ordered contracts could end prematurely 2017-04-21 15:52:21 -04:00
Andrew DanielsandGitHub acf345e1d3 PERF: Optimize session close lookups in resample bar reader (#1749)
Optimize session close lookups in MinuteResampleSessionBarReader:

- Adds `session_closes_in_range` method (along with
  `session_opens_in_range`) to TradingCalendar to allow vectorized
  retrieval of all values in a range of sessions.
- Improves code path for resampling a single session's worth of data (as
  is the case when calling `get_value`), since we don't actually need to
  look up the close minute.
2017-04-11 16:35:04 -04:00
Andrew DanielsandGitHub 26ffda9ca1 Merge pull request #1747 from quantopian/calendar-perf-improvements
Improve TradingCalendar perf with scalar-optimized accesses
2017-04-11 10:15:28 -04:00
Andrew Daniels 1d7d3fe33f PERF: Only get session close in MinuteResampleSessionBarReader
We only need the close, not the open.
2017-04-10 17:23:07 -04:00
Andrew Daniels 12f1429a8c PERF: Use scalar lookups for TradingCalendar.schedule
When retrieving the open and close for a given session, we only care
about the scalar values, so using DataFrame.at instead of DataFrame.loc
is significantly faster.
2017-04-10 17:23:07 -04:00
Maya TydykovandGitHub 0c88ba21b9 Merge pull request #1737 from quantopian/bump-blaze
BLD: bump blaze
2017-04-10 16:22:09 -04:00
David MichalowiczandGitHub 9e0cf08c18 Merge pull request #1738 from quantopian/slippage-and-commissions-futures
Add preliminary support for Futures slippage models
2017-04-10 15:05:28 -04:00
Andrew DanielsandGitHub f9d55cf9cd Merge pull request #1742 from quantopian/only-get-value-once
MAINT: Refactor DataPortal._get_minute_spot_value to avoid two lookups
2017-04-10 14:56:29 -04:00
dmichalowicz bc27e369ff ENH: Preliminary support for Futures slippage and commission models 2017-04-10 14:37:20 -04:00
David MichalowiczandGitHub d5aa5b0c36 Merge pull request #1745 from quantopian/reconcile-default-args
Make certain continuous future arguments optional
2017-04-10 11:24:50 -04:00
dmichalowicz ec8880a066 API: Make certain continuous future arguments optional 2017-04-07 14:02:36 -04:00
Maya TydykovandGitHub 9350759119 Merge pull request #1739 from quantopian/fix-zipline-and-pandas-bug
Fix zipline and pandas bug
2017-04-07 12:22:06 -04:00
David MichalowiczandGitHub b35ec1b5cd Merge pull request #1743 from quantopian/premature-continuous-futures
OrderedContracts chain could sometimes terminate on first contract
2017-04-07 11:03:33 -04:00
dmichalowicz 845dea3e5b BUG: OrderedContracts chain could sometimes terminate on first contract 2017-04-07 10:01:22 -04:00
Joe JevnikandJoe Jevnik e6f2f562b3 BUG: reload_symbol_maps should clear the equity_supplementary_maps 2017-04-06 19:04:09 -04:00
Andrew DanielsandGitHub 569998179a Merge pull request #1735 from quantopian/speedup-daily-history-aggregator-closes
PERF: Avoid repeated recursive calls when getting forward-filled close
2017-04-06 10:24:29 -04:00
Andrew Daniels f8eced41bf PERF: Avoid repeated recursive calls when getting forward-filled close
Instead of recursively calling `DailyHistoryAggregator.closes` until we
find a non-nan close, we can instead call `load_raw_arrays` once, and
find the value from the returned array.
2017-04-06 09:51:01 -04:00
Andrew Daniels ad7f727c47 MAINT: Refactor DataPortal._get_minute_spot_value to avoid two lookups 2017-04-06 08:54:17 -04:00
David MichalowiczandGitHub 1212d2f0a1 Merge pull request #1741 from quantopian/remove-adj-method
Remove ContinuousFuture adjustment method
2017-04-05 16:24:24 -04:00
dmichalowicz 276b65f527 CRUFT: Remove ContinuousFuture adjustment method 2017-04-05 15:25:50 -04:00
Freddie VargusandGitHub 18b0def1a1 Merge pull request #1731 from quantopian/update-assetdbwriter-docs
DOC: Show exchange as required for equities
2017-04-04 23:27:50 -04:00
Scott SandersonandGitHub e914b23c80 Merge pull request #1740 from quantopian/guarantee-can-trade-order
BUG: Return from can_trade in same order as input.
2017-04-04 18:39:53 -04:00
David MichalowiczandGitHub 340a66afd5 Merge pull request #1729 from quantopian/us-futures-cal-in-tests
Use 'us_futures' calendar in test fixtures
2017-04-04 17:49:51 -04:00
Scott Sanderson d289e86895 MAINT: Guarantee bool dtype for can_trade. 2017-04-04 17:26:38 -04:00
dmichalowicz c701f200c2 REV: Only use benchmark csv files in source for testing 2017-04-04 17:18:49 -04:00
Scott Sanderson 65381ecbcd BUG: Return from can_trade in same order as input.
This matches the behavior of history and data.current.
2017-04-04 17:12:21 -04:00
Maya Tydykov 63ad5a5b55 BUG: address pandas normalization bug on non-sorted DT index 2017-04-04 17:00:32 -04:00
Maya Tydykov 63951ad9e9 BUG: test DatetimeIndex equality correctly 2017-04-04 17:00:16 -04:00
Freddie Vargus 3dfc20ec1c DOC: Show exchange required for equities 2017-04-04 15:02:00 -04:00
dmichalowicz dee19a0d8b TST: Make TradingEnvironment resources static 2017-04-04 10:58:45 -04:00
Maya Tydykov a89d05dd56 BLD: bump blaze 2017-04-03 15:20:49 -04:00
dmichalowicz 0c49c5bbc7 TST: Use 'us_futures' calendar in test fixtures 2017-04-03 10:18:03 -04:00
Eddie HebertandGitHub 84b24d2cee Merge pull request #1734 from quantopian/prepare-for-validity-checks
MAINT: Prepare parameter check for adding an additional check.
2017-03-30 14:02:03 -04:00
David MichalowiczandGitHub 0182d62cc8 Merge pull request #1730 from quantopian/no-current-contract
Add safeguard if current contract of continuous future is None
2017-03-30 13:32:15 -04:00
dmichalowicz 69a0e5c31b BUG: Getting continuous future current contract failed on None 2017-03-30 12:09:55 -04:00
Eddie Hebert fc65ac33ca MAINT: Prepare parameter check for adding an additional check.
Should be no functional change.

By making the raise on `if not isinstance` instead of doing a continue on `if
isinstance` (with a raise at the end of the loop if no 'good' conditions were
met'), the function should be more amenable to adding an additional validity
check, after the type check passes.

This is on the path to adding an additional validity checks parameter to
`check_parameters`, e.g. adding an 'is positive' check.
2017-03-30 10:47:29 -04:00
David MichalowiczandGitHub 0bcdb640ca Merge pull request #1726 from quantopian/cf-adjustment-arg
Make continuous future adjustment style an argument
2017-03-29 09:15:22 -04:00
dmichalowicz f0f8bac2ab EHN: Make continuous future adjustment style an argument 2017-03-29 08:49:12 -04:00
David MichalowiczandGitHub 0d0473cb44 Merge pull request #1721 from quantopian/out-of-bounds-price
Negative indexing in cython without wraparound
2017-03-29 08:46:50 -04:00
dmichalowicz 066a7776d2 BUG: Open and close resampling code could hit index errors 2017-03-28 16:06:29 -04:00
Eddie HebertandGitHub 35203c6904 Merge pull request #1728 from quantopian/rework-resample-close
MAINT: Clear up naming and logic in resample close.
2017-03-28 14:02:27 -04:00
Eddie Hebert 2792de1f92 MAINT: Clear up naming and logic in resample close.
- Instead of maintaining a separate `j` value, set the bounds of the range so
that `i` is the values emitted by the range.
- Change `close_loc` to `prev_close_loc` since the market close location is used
to ensure that the data index stops at the market open if the entire day is
nans.
- Change the setting of `loc` to be done before the loop which check for nans,
instead of setting to the previous close loc at the end of the loop.

This prepares for a separate fix to prevent out of bounds access when the first
session has nans for all minutes.
2017-03-28 13:30:12 -04:00
Eddie HebertandGitHub ee19186e51 Merge pull request #1727 from quantopian/resample-whitespace-cleanup
STY: Cleanup trailing whitespace in resample module.
2017-03-28 13:00:33 -04:00
Eddie Hebert 63c80109ec STY: Cleanup trailing whitespace in resample module. 2017-03-28 12:16:39 -04:00
Jean BredecheandPaul Sutherland 81b943c61d ENH: Allow override of order amount rounding. (#1722)
* ENH: Use regular rounding to calculate order amounts.

We previously tried to prevent accidental over-ordering by truncating
orders down unless they were within 1e-4 of the next higher integer.
Unfortunately, this makes it easy for a sell order to be one share short
of the desired position.

Using regular rounding treats both buys and sells in the same way.

* ENH keep non-rounding behavior consistent, but leave code structured to make easier to override

* DOC make round_order public and describe behavior in docstring
2017-03-27 20:44:12 -04:00
Freddie VargusandGitHub 4916fb5fcc Merge pull request #1723 from quantopian/deploy-docs-without-path.py
ENH: Remove path.py as its not a dependency
2017-03-27 19:26:20 -04:00
Freddie Vargus 3e1f3c1e54 ENH: Remove path.py as its not a dependency
MAINT: Add try finally block to deal with exceptions
2017-03-27 18:53:09 -04:00
Freddie VargusandGitHub 0e3421ead8 Merge pull request #1725 from quantopian/adhoc-cfe-calendar-test
TST: Adhoc holidays in CFEExchangeCalendar
2017-03-27 18:17:09 -04:00
Freddie VargusandGitHub 2010a7faf8 STY: Add newline 2017-03-27 09:59:08 -04:00
Freddie Vargus b81ddd7d73 TST: Test for adhoc holidays in CFEExchangeCalendar 2017-03-27 09:56:40 -04:00
Freddie VargusandGitHub 02b26a97a5 Merge pull request #1698 from trical09/master
ENH: Add CFE Adhoc Holidays
2017-03-26 19:30:04 -04:00
Maxwell RoundsandMaxwell Rounds 24ce67a7cf ENH: Adding CFE Adhoc Holidays
The CFE was closed along with the NYSE in observation of the days of
mourning in honor of the passing of presidents Gerald Ford and Ronald
Reagan. The CFE also observed the closures due to Hurricane Sandy,
along with NYSE. Adding those adhoc holidays to exchange_calendar_cfe
and removing them from cfe.csv in tests. To fit with
USNationalDaysofMourning, also removing the closure in observation of
the day of mourning in honor of the passing of president Nixon in
1994, despite the fact that the exchange did not exist at that time.

Signed-off-by: Maxwell Rounds <maxwell.j.rounds@gmail.com>
2017-03-26 15:54:14 -07:00
David MichalowiczandGitHub 7ef17ae3af Merge pull request #1718 from quantopian/more-generic
Add ContinuousFuture to lookup_generic
2017-03-25 09:23:35 -04:00
David MichalowiczandGitHub 5b27790126 Merge pull request #1719 from quantopian/vectorize-spot-value
Allow DataPortal.get_spot_value to accept multiple assets
2017-03-25 09:22:59 -04:00
dmichalowicz c0355af316 ENH: Add ContinuousFuture to lookup_generic 2017-03-25 09:04:17 -04:00
dmichalowicz 8a25ac3af0 ENH: Allow DataPortal.get_spot_value to accept multiple assets 2017-03-25 09:02:10 -04:00
Andrew DanielsandGitHub c0a76a5303 ENH: Adds StaticSids pipeline filter (#1717)
Useful for avoiding the need to create Asset objects when sids are
easier to use.

This is based off the existing implementation of StaticAssets, and
StaticAssets is now implemented as a wrapper around StaticSids.
2017-03-22 14:28:54 -04:00
Freddie VargusandGitHub 2860708a44 Merge pull request #1683 from shadiakiki1986/bugfix_index_should_be_int
BUG: Convert index to int so that the pandas indexing doesnt fail
2017-03-16 13:36:10 -04:00
David MichalowiczandGitHub 78e56c33ef Merge pull request #1715 from quantopian/missing-cf-error
Better error message for non-existent root symbol
2017-03-16 12:02:15 -04:00
dmichalowicz 825ba5717e ENH: Better error message for non-existent root symbol 2017-03-16 11:18:17 -04:00
David MichalowiczandGitHub f561e2ea54 Merge pull request #1714 from quantopian/test-fixture-fix
Equity daily data test fixture was using wrong sids
2017-03-15 16:44:05 -04:00
Maya TydykovandGitHub 83756d4660 Merge pull request #1710 from quantopian/sort-pipeline-data-on-asofdate
Sort pipeline data on asofdate
2017-03-15 14:40:11 -04:00
Maya Tydykov 58fb830ebd BUG: sort data on asof_date to resolve ts conflicts
MAINT: fix arg default and update docstring
2017-03-15 14:10:58 -04:00
Jean BredecheandGitHub 8292264229 Merge pull request #1713 from quantopian/teach-data-about-current-session-minutes
ENH: teach BarData about current session's minutes
2017-03-15 14:02:17 -04:00
Jean Bredeche c9254d395d ENH: teach BarData about current session's minutes 2017-03-15 13:40:33 -04:00
dmichalowicz fa56fe4954 TST: Equity daily data test fixture was using wrong sids 2017-03-15 13:16:45 -04:00
Eddie HebertandGitHub 3909269806 Merge pull request #1712 from quantopian/adjustment-cython-checker-recs
MAINT: Apply linter recommendations to adjustments module.
2017-03-15 12:38:00 -04:00
Eddie Hebert 4071a52702 MAINT: Apply linter recommendations to adjustments module.
Remove unused variables.

Add type for values used to access arrays.
2017-03-15 11:26:38 -04:00
Shadi Akiki 9a7e847ab7 BUG: use integer division for index so that pandas indexing doesnt fail 2017-03-13 07:42:51 +00:00
Freddie VargusandGitHub b95088ca76 Merge pull request #1709 from quantopian/whatsnew-1.1.1
DOC: Add whatsnew for 1.1.1
2017-03-10 18:07:04 -05:00
Freddie Vargus dcf1210043 DOC: Add whatsnew for 1.1.1 2017-03-10 17:46:13 -05:00
Freddie VargusandRichard Frank 40fc1c9185 REL: Update stubs for 1.1.0 release 2017-03-10 17:19:57 -05:00
Joe JevnikandJoe Jevnik beb4bd8c6e BUG: fix label array code dtype condense 2017-03-08 20:54:57 -05:00
Richard FrankandGitHub 85eef5cb6b Merge pull request #1699 from quantopian/yahoo-url-update
MAINT: Updated yahoo url for SSL
2017-03-08 16:04:51 -05:00
Freddie VargusandGitHub 3004108464 Merge pull request #1681 from quantopian/1.1.0-whatsnew
DOC: Draft whatsnew for 1.1.0 release
2017-03-08 15:51:16 -05:00
Freddie Vargus d3b9da83c9 DOC: Write up whatsnew for 1.1.0 release
DOC: Clarify changes and fix formatting

DOC: Remove 1.0.3 whatsnew

DOC: More formatting

DOC: Remove superfluous info

DOC: Change deploy command

DOC: Fix typo

DOC: Add mention of winsorize factor

DOC: Change date of release

DOC: Remove date for now

DOC: Change release to development
2017-03-08 14:53:47 -05:00
Ana RuelasandGitHub 476e86a041 Merge pull request #1703 from quantopian/ceil-bugfix
BUG: ceil returns float, int needed for array indexing
2017-03-08 11:35:31 -05:00
Ana Ruelas 5d77a4bf94 BUG: ceil returns float, int needed for array indexing 2017-03-08 11:05:54 -05:00
David MichalowiczandGitHub 2d1108fb7e Merge pull request #1702 from quantopian/reader-last-dates
Set data portal last trading session/minute if passed
2017-03-08 10:04:24 -05:00
dmichalowicz 6596c03351 BUG: Set data portal last trading session if passed 2017-03-08 09:07:03 -05:00
Ana RuelasandGitHub de3702ab59 Merge pull request #1696 from quantopian/add-winsorize
ENH: Add winsorize factor
2017-03-07 18:07:09 -05:00
Ana Ruelas 9252b62b2b TST: Add tests for winsorize factor 2017-03-07 17:14:27 -05:00
Ana Ruelas 799bad957d ENH: Add winsorize factor 2017-03-06 14:08:28 -05:00
Richard Frank cb76f1fc16 MAINT: Updated yahoo url for SSL 2017-03-05 17:37:45 -05:00
Joe JevnikandGitHub cfdbe883b1 Merge pull request #1672 from quantopian/narrow-labelarray
narrow labelarray
2017-03-02 19:32:56 -05:00
Joe Jevnik 44563d351b TST: add roundtrip check 2017-03-01 15:15:16 -05:00
Ana RuelasandGitHub fb10d9346b Merge pull request #1694 from quantopian/invalid-test-data
ENH: Make invalid data behavior optional
2017-03-01 11:13:15 -05:00
Ana Ruelas 0d4ca54900 ENH: Make invalid data behavior optional 2017-03-01 10:41:30 -05:00
Scott SandersonandGitHub 270e670551 Merge pull request #1693 from quantopian/nat-for-dtype-enh
ENH: make NaT_for_dtype coerce the input to a dtype
2017-02-28 23:32:54 -05:00
Joe Jevnik a8d6ecd545 ENH: make LabelArray.from_codes_and_metadata public 2017-02-28 23:12:55 -05:00
Joe Jevnik a4e445153c ENH: make NaT_for_dtype coerce the input to a dtype 2017-02-28 22:49:17 -05:00
Alexey DegtyarevandRichard Frank dd7fa4ba25 DOC: Fix typo in -k/--keep-last option description 2017-02-28 22:27:18 -05:00
Richard FrankandGitHub 83ab7b3250 Merge pull request #1692 from quantopian/pin-blaze-deps
MAINT: Pin specific versions of blaze dependencies
2017-02-28 20:59:27 -05:00
Richard Frank 5b7124ac6f BLD: Pin Miniconda version on Windows
as we do on linux. The url for latest Miniconda2 was changed anyway.
2017-02-28 19:40:11 -05:00
Richard Frank eef59f842c MAINT: Pin specific versions of blaze dependencies 2017-02-28 19:40:10 -05:00
Jean BredecheandGitHub d176ba4d85 Merge pull request #1689 from quantopian/slippage_needs_asdict
Rename _attrs_to_check to asdict
2017-02-23 12:20:51 -05:00
Jean Bredeche cf063abcf1 Rename _attrs_to_check to asdict 2017-02-23 11:32:04 -05:00
Richard Frank 93c50899f8 BLD: Don't need to build this branch anymore
It was merged long ago.
2017-02-21 11:12:05 -05:00
Richard FrankandGitHub 159ed7321f Merge pull request #1688 from quantopian/conda-root-version
BLD: Pin python version of conda root env to python 2
2017-02-21 11:10:30 -05:00
Richard Frank ec447198c6 BLD: Pin python version of conda root env to python 2
Print conda info on travis
2017-02-20 18:51:40 -05:00
Andrew DanielsandGitHub 8e1f8d75f5 MAINT: Removes unnecessary capital_base arg to TradingAlgorithm (#1677)
Capital base is included in the sim params, so we should define the
value there, or use the default.

This change also unifies the default capital base as 1e5, as was
previously defined in algorithm.py.
2017-02-17 09:04:50 -05:00
David MichalowiczandGitHub 383d56b3bc Merge pull request #1680 from quantopian/rolls-bias
Eliminate Possible Bias in Volume Rolls
2017-02-16 09:26:32 -05:00
dmichalowicz 63063aa709 ENH: Eliminate potential look-ahead bias in volume rolls 2017-02-16 09:01:16 -05:00
Maya TydykovandGitHub 5ab0880ad7 Merge pull request #1684 from quantopian/fix-earnings-estimates-1-day-bug
BUG: fix loader bug for 1 day
2017-02-15 17:20:31 -05:00
Maya Tydykov 59acadbccf BUG: fix loader bug for 1 day 2017-02-15 16:44:45 -05:00
Andrew DanielsandGitHub c2560c6079 TST: Adds TestingSlippage slippage model (#1679)
Allows specifying a constant number of shares filled per tick.

Also adds the WithConstantEquityMinuteBarData fixture, relocated from
internal repo.
2017-02-09 08:56:15 -05:00
Eddie HebertandGitHub e81287e8e1 Merge pull request #1678 from quantopian/flake8-line-too-longs
STY: Wrap/reformat lines over 80 chars.
2017-02-09 05:57:00 -05:00
Andrew LiangandGitHub 54c8e6c358 Merge pull request #1676 from quantopian/param_sapce
TEST: Allow parameter_space to work on repeated calls of test
2017-02-08 18:39:51 -05:00
Andrew Liang cb6c5f09a6 TEST: Allow parameter_space to work on repeated calls of test
If we have a test that's being called more than once (i.e. two
test cases, both subclasses of the same base test case, with
different setup but calling the same test), allow the subsequent
calls to re-consume the same params
2017-02-08 18:19:14 -05:00
Eddie Hebert 8878d0ddd5 STY: Wrap/reformat lines over 80 chars.
Newer versions of flake8 detect these versions, though current zipline version
of flake8 does not.
2017-02-08 00:47:33 -05:00
Joe Jevnik b4ed1fcff3 MAINT: windows definition for log2 2017-02-07 17:01:37 -05:00
Joe Jevnik 735d98fb6e TST: add tests for inferred width labelarray 2017-02-07 16:28:13 -05:00
David MichalowiczandGitHub cb41be012f Merge pull request #1671 from quantopian/new-futures-hours
Change to a 10.5 hour futures calendar
2017-02-06 12:53:23 -05:00
dmichalowicz db2440871e Change to a 10.5 hour futures calendar 2017-02-06 11:41:29 -05:00
Gus GordonandGitHub 26558743ba Bump empyrical to 0.2.2 (#1674)
* Bump empyrical to 0.2.2

* Update example data for tests
2017-02-04 16:14:33 -05:00
Eddie HebertandGitHub 7a0a214ac1 Merge pull request #1673 from quantopian/remove-duplicate-test-expiration-date
TST: Remove duplicate key in fixture config.
2017-02-03 00:30:11 -05:00
Eddie Hebert 11a406c67a TST: Remove duplicate key in fixture config.
Should be no functional change.
2017-02-02 23:10:14 -05:00
Joe Jevnik d378c9fca3 ENH: store the 'codes' for a labelarray in the narrowest int type possible 2017-02-02 20:58:36 -05:00
Freddie VargusandGitHub 5fbd0251aa Merge pull request #1625 from quantopian/ambiguous-cli-shortopt
ENH: change the clean --before shortopt from -b to -e
2017-02-02 14:04:07 -05:00
Joe JevnikandJoe Jevnik d9321f4795 TST: assert_equal dispatch for tuples 2017-02-01 19:42:10 -05:00
Andrew LiangandGitHub 38367b6794 Merge pull request #1669 from quantopian/expect_strict_bounds
ENH: Decorator to check inputs fall EXCLUSIVELY between bounds
2017-02-01 14:01:26 -05:00
Andrew Liang 6cd6163fd2 ENH: Decorator to check inputs fall EXCLUSIVELY between bounds
Make a new decorator, expect_strictly_bounds, which shares logic
with the existing expect_bounded (which checks that inputs fall
INCLUSIVELY between bounds),
2017-02-01 13:38:27 -05:00
Maya TydykovandGitHub bb36ec1224 Merge pull request #1661 from quantopian/optionally-apply-deltas-adjustments
Optionally apply deltas adjustments
2017-01-31 15:40:43 -05:00
Maya Tydykov dda5334580 TST: add arg to test assertion 2017-01-31 15:19:05 -05:00
Maya Tydykov bd06ff14ed MAINT: optionally apply deltas adjustments based on info from dataset 2017-01-31 15:19:03 -05:00
Scott SandersonandGitHub 58850b86ad Merge pull request #1667 from quantopian/pricing-fixture-cleanups
Pricing fixture cleanups
2017-01-31 10:32:17 -05:00
Maya TydykovandGitHub 9786483ec0 Merge pull request #1665 from quantopian/determine_overwrite_type_dynamically
Determine overwrite type dynamically
2017-01-31 10:06:21 -05:00
Maya Tydykov 9cdd696467 TST: add test cases for int and object dispatching 2017-01-31 09:43:39 -05:00
Maya Tydykov c5efba0c8a MAINT: make obj adjustment dispatching more granular 2017-01-31 09:43:39 -05:00
Maya Tydykov 08b159d5da ENH: add Int64Overwrite and dispatching for it
BUG: column value should be float

DOC: update docs
2017-01-31 09:43:37 -05:00
Maya Tydykov 98a8fdfb09 MAINT: determine core loader overwrite types dynamically
TST: update test to reflect adjustment mapping change
2017-01-31 09:43:34 -05:00
Scott Sanderson f14e8e00ef MAINT: Raise LookupError instead of KeyError.
KeyError calls __repr__ on its input, which makes it really unpleasant
to read multi-line strings.
2017-01-30 22:13:18 -05:00
Vikram NarayanandGitHub 96ba361e36 Merge pull request #1666 from quantopian/add_class_callback_args
MAINT: pass args, kwargs to add_class_callback
2017-01-30 15:43:40 -05:00
Scott Sanderson 938bb70227 DOC: Update out of date docstring. 2017-01-30 13:33:21 -05:00
Scott Sanderson caee313012 ENH: Align daily/minute bar lookbacks by default.
When EQUITY_DAILY_BAR_SOURCE_FROM_MINUTE is set, use
EQUITY_MINUTE_BAR_LOOKBACK_DAYS as the default value for
EQUITY_DAILY_BAR_LOOKBACK_DAYS.

Without this, trying to run a minutely backtest in a test setting only
EQUITY_MINUTE_BAR_LOOKBACK_DAYS and EQUITY_DAILY_BAR_SOURCE_FROM_MINUTE
fails because the benchmark creation process makes a daily history call
for the entire period of the backtest, which then fails because the
equity daily bar calendar is shorter than the equity minute bar
calendar.

I can't imagine a circumstance in which you'd want the daily bar
calendar to be shorter than the minute bar calendar when you're sourcing
daily bars from minutes, so this change makes that the default behavior
unless it's explicitly overridden.
2017-01-30 13:28:00 -05:00
Scott Sanderson d82bf7a1e3 BUG: Fix bad error handling in history loader.
Fixes a bug where we'd fail to raise an error if the start/end of a
history window call don't aren't in the loader's calendar.

We were started dropping this error after a previous change swapped out
calls to `index.get_loc` with calls to `index.searchsorted` to avoid
creating hash tables in pandas.
2017-01-30 13:23:47 -05:00
Scott Sanderson e5f403deca ENH: Add direct methods for session start/end.
Rather than having to do 'start, _ = cal.open_and_close_for_session(dt)'
to get just the start, we can now do 'start = cal.session_start(dt)'.
2017-01-30 13:00:45 -05:00
vikram-narayan beea8624d1 MAINT: pass args, kwargs to add_class_callback 2017-01-27 18:19:23 -05:00
Eddie HebertandGitHub 484f80dd01 Merge pull request #1663 from quantopian/support-futures-in-lookup-generic
ENH: Add futures support for generic asset lookup.
2017-01-26 21:41:13 -05:00
Eddie Hebert 1302d4152f ENH: Add futures support for generic asset lookup.
Attempt to lookup up the symbol in the futures table, after attempting to look
up the symbol in the equities table.
2017-01-26 21:08:30 -05:00
Eddie HebertandGitHub 8bf2da6ac0 Merge pull request #1662 from quantopian/remove-unused-future-methonds-from-asset-finder
MAINT: Remove unused futures related methods from asset finder.
2017-01-26 16:06:32 -05:00
Eddie Hebert 2a9d8cebc3 MAINT: Remove unused futures related methods from asset finder.
These methods became unused during the course of reworking futures to support
continuous futures.
2017-01-26 15:41:30 -05:00
David MichalowiczandGitHub 0d1e5e2d1c Merge pull request #1659 from quantopian/remove-position-multipliers
Multipliers were not removed when closing a position
2017-01-25 17:48:48 -05:00
dmichalowicz 44088dd4d5 BUG: Multipliers were not removed when closing a position 2017-01-25 17:23:09 -05:00
Jean BredecheandGitHub b080d337f5 Merge pull request #1657 from quantopian/compare-slippage-models
ENH: Solidify equality comparisons for SlippageModel classes
2017-01-24 11:47:29 -05:00
Jean Bredeche ccddc86d6b ENH: Solidify equality comparisons for SlippageModel classes 2017-01-24 11:28:32 -05:00
Eddie HebertandGitHub 9ea1ee443a Merge pull request #1656 from quantopian/fix-open-minutes-for-append
BUG: Fix end session metadata for minute bar writer.
2017-01-22 15:58:27 -05:00
Eddie Hebert b90091e494 BUG: Fix end session metadata for minute bar writer.
When opening with a new `end_session`, i.e. opening for append, write the new
end session to the metadata.

Fixes an issue where the calendar on minute bar readers did not include the
recently appended day, causing reads on the last values to fail.

According, update append test to read a value, instead of checking table length.
2017-01-22 15:14:05 -05:00
David MichalowiczandGitHub 364f5cc199 Merge pull request #1644 from quantopian/closed-means-closed
Don't allow ordering assets after their auto close date
2017-01-20 10:19:27 -05:00
dmichalowicz 83a221e986 BUG: can_trade was true for assets after their auto close date 2017-01-20 09:54:30 -05:00
Jean BredecheandGitHub f0b5b21c67 Merge pull request #1655 from quantopian/fix-py3-error
BUG: fix a py3 invalid char
2017-01-19 21:03:28 -05:00
Jean Bredeche efcc87e089 BUG: fix a py3 invalid char 2017-01-19 20:43:48 -05:00
Jean BredecheandGitHub 006df906b0 Merge pull request #1654 from quantopian/tell-me-the-current-session
ENH: add current_session property to BarData
2017-01-19 17:09:30 -05:00
Jean Bredeche 1f56f20a7f ENH: add current_session property to BarData 2017-01-19 16:53:49 -05:00
Maya TydykovandGitHub 25f826d5c7 Merge pull request #1643 from quantopian/events-loader-handle-empty-raw-data
Events loader handle empty raw data
2017-01-19 13:01:43 -05:00
Maya Tydykov ecbc7f890b BUG: make the events loader handle empty raw data
TST: add test case for empty raw events data

BUG: update for python compatibility

MAINT: Simplify assertion for empty events case.

DOC: Add comments on indexer unpacking.

MAINT: move some config to test method
2017-01-19 12:00:49 -05:00
Jean BredecheandGitHub fad98672e0 Merge pull request #1650 from quantopian/slippage-cleanup
ENH: Small refactoring of fill price check.
2017-01-18 09:57:03 -05:00
Jean Bredeche 7e2838744c ENH: Small refactoring of fill price check. 2017-01-18 09:22:05 -05:00
Eddie HebertandGitHub 962c414ab7 Merge pull request #1649 from quantopian/easier-open-minute-bars-for-append-truncate
Easier open minute bars for append and truncate
2017-01-17 17:56:17 -05:00
Eddie Hebert df87dfb227 ENH: Add sorted to sid list when truncating.
For repeatable order of truncates between invocations.
2017-01-17 17:25:28 -05:00
Eddie Hebert 1d75143f54 ENH: Add a method to open existing minute bar directory.
Remove need for a consumer that is editing an existing minute bars directory to
reread the values which should not change from the metadata.

Add a test to the append on new day and truncate, which would be the common
usage of this method.
2017-01-17 17:25:27 -05:00
Eddie HebertandGitHub 2af63dfab7 Merge pull request #1646 from quantopian/update-toolz
BLD: Use latest version of toolz.
2017-01-13 16:09:55 -05:00
Eddie Hebert cb50959efc BLD: Use latest version of toolz.
Also, add requirement of cytoolz to blaze reqs so that toolz and cytoolz are
on the same version.
2017-01-13 15:42:59 -05:00
Scott SandersonandGitHub a06503d8ec Merge pull request #1645 from quantopian/nitpick-some-more-why-dont-you
STY: Simplify style in conditional.
2017-01-12 22:26:21 -05:00
Scott Sanderson 57b09ce1d7 STY: Simplify style in conditional. 2017-01-12 22:03:35 -05:00
Richard Frank 64f77eb3e4 MAINT: Update and pin more dev requirements 2017-01-08 14:07:55 -05:00
Richard Frank 50c096c3e9 MAINT: Pin exact versions of Mako, MarkupSafe, requests-file
which are transitive dependencies of zipline
2017-01-07 17:57:29 -05:00
Eddie HebertandGitHub 1e51dbec0a STY: Use def statements instead of lambda assignment. (#1639)
From pep-0008:

```
Always use a def statement instead of an assignment statement that binds a
lambda expression directly to an identifier.

Yes:

def f(x): return 2*x
No:

f = lambda x: 2*x

The first form means that the name of the resulting function object is
specifically 'f' instead of the generic '<lambda>'. This is more useful for
tracebacks and string representations in general. The use of the assignment
statement eliminates the sole benefit a lambda expression can offer over an
explicit def statement (i.e. that it can be embedded inside a larger expression)
```
2017-01-06 13:39:07 -05:00
Richard FrankandGitHub a1f09cffb8 Merge pull request #1638 from luca-s/IchimokuKinkoHyo_fix
BUG: IchimokuKinkoHyo techinical factor has wrong default inputs
2017-01-06 13:23:52 -05:00
Luca b5ce101f5a BUG: IchimokuKinkoHyo techinical factor has wrong default inputs 2017-01-06 16:06:05 +01:00
Eddie HebertandGitHub aed2c64c99 BLD: Update numexpr to latest to satisfy tables deps. (#1636)
* BLD: Update numexpr to latest to satisfy tables deps.

tables 3.3.0 requires numexpr >= 2.5.2

Also remove numexpr conda recipe.
2017-01-05 15:27:24 -05:00
Kathryn GlowinskiandGitHub dd560ba5f0 BUG: Datetimes should be converted in utc. (#1635)
* BUG: Datetimes should be converted in utc.

* DOC: Making note of UTC req. and moving comment.
2017-01-05 14:13:23 -05:00
Eddie HebertandEddie Hebert c1fe909dde Remove tables from custom conda scripts.
Use anaconda hosted instead.
2017-01-04 12:09:10 -05:00
Eddie HebertandEddie Hebert 2d5f5491ee Swap name instead.
Package is named pytables on conda.
2017-01-04 12:09:10 -05:00
Eddie HebertandEddie Hebert a3dfa4a6fa Add hdf5 install. 2017-01-04 12:09:10 -05:00
Eddie HebertandEddie Hebert 037b2b0003 Remove tables from travis. 2017-01-04 12:09:10 -05:00
Eddie HebertandEddie Hebert d023a8ed4f Use tables instead of pytables. 2017-01-04 12:09:10 -05:00
Eddie HebertandEddie Hebert dfdf26e310 Use conda skeleton for pytables. 2017-01-04 12:09:10 -05:00
Eddie HebertandEddie Hebert e4c0120876 Attemp to add conda package. 2017-01-04 12:09:10 -05:00
Eddie HebertandEddie Hebert 9262381d17 Fix double equals in conda pytables. 2017-01-04 12:09:10 -05:00
Eddie HebertandEddie Hebert 225b6fe119 Update tables. 2017-01-04 12:09:10 -05:00
Eddie HebertandEddie Hebert 5a8443b5f1 Add pytables for travis. 2017-01-04 12:09:10 -05:00
Eddie HebertandEddie Hebert e913519734 ENH: Add a reader writer pair for HDF5 minute bar updates.
This format is intended for storing data for all sids of an asset type,
e.g. equities or futures for a session. bcolz is not used to avoid the overhead
of creating the directories and files for each asset (which numbers around ~8000
for active equities) can be removed since the update is meant to be read at
once, instead of supporting the random access pattern needed by the simulation.

This patch only adds the reader/writer pair, with the management of finding the
paths to delta files and the application of the updates to the bcolz write left
to internal loader code.

Also, the update reader interface is intentionally constrained to the data for
an entire session to allow for an implementation that allows for mid-session updates.
2017-01-04 12:09:10 -05:00
Scott SandersonandGitHub 3095f8c573 Merge pull request #1627 from quantopian/vectorized-symbol-map
ENH: Add vectorized lookup_symbol.
2016-12-28 15:10:14 -05:00
Scott Sanderson 4475a42b15 DOC: Add note on lookup_symbols. 2016-12-28 14:43:15 -05:00
Scott Sanderson 0aa4f129c1 TEST: Tweaks to vectorized symbol tests.
- Test against an empty list.
- Don't test empty share class lookups.
- Add another comprehension test for completeness.
2016-12-28 14:40:18 -05:00
Scott Sanderson fd74aad31c ENH: Add vectorized lookup_symbol.
Currently only supports one as_of date.c
2016-12-28 12:31:50 -05:00
Kathryn GlowinskiandGitHub df6cb62925 Adjustments to Component Dfs (#1620)
* ENH: SQLiteAdjustmentReader can return DF versions of tables.
2016-12-27 13:44:17 -05:00
Joe Jevnik d2cc337202 ENH: change the clean --before shortopt from -b to -e 2016-12-25 19:22:28 -05:00
David MichalowiczandGitHub 4b69a253ec Merge pull request #1623 from quantopian/futures-scaling-factor
TST: Extra test for reading/writing ohlc ratios
2016-12-22 15:01:42 -05:00
dmichalowicz 56b5ac686a TST: Extra test for reading/writing ohlc ratios 2016-12-22 14:34:46 -05:00
Andrew DanielsandGitHub c6ad893c14 TST: Populate equity_supplementary_mappings from WithAssetFinder (#1622) 2016-12-22 11:07:30 -05:00
Richard FrankandGitHub 09318df534 Merge pull request #1596 from quantopian/order_batch
Order batch
2016-12-21 20:41:35 -05:00
Richard Frank 7ab0b08e95 MAINT: Filter out null orders 2016-12-20 19:27:29 -05:00
Richard Frank 30bc01dbc0 MAINT: Some cleanup while working on batch ordering 2016-12-20 19:27:28 -05:00
Richard Frank 555d460d26 TST: Ensure batch_order_target_percent orders like order_target_percent 2016-12-20 19:27:28 -05:00
Richard Frank 0ee76d1e11 DOC: Updated return types in docstrings 2016-12-20 19:27:28 -05:00
Richard Frank edab970973 ENH: Renamed to batch_order and added batch_order_target_percent 2016-12-20 11:58:05 -05:00
Richard Frank 83d0c45ec3 MAINT: Renamed order_batch parameter and added docs 2016-12-20 11:57:27 -05:00
Richard Frank dea157741f MAINT: Allow for orders with id 0 2016-12-20 11:57:26 -05:00
Richard Frank 12b6c273d1 TST: Added test for order_batch 2016-12-20 11:57:26 -05:00
Richard Frank d71feec46d MAINT: Moved common asset lookup to fixture init
Also can use class's asset_finder instead of via env
2016-12-20 11:57:26 -05:00
Richard Frank 47633b1601 MAINT: Removed unnecessary override 2016-12-20 11:57:26 -05:00
Richard Frank 3457b106fb ENH: Blotter support for ordering a batch 2016-12-20 11:57:26 -05:00
Richard Frank 8314586612 MAINT: Factored out order arg calculation methods
so callers can use them to construct args for a batch of orders
2016-12-20 11:57:26 -05:00
Andrew DanielsandGitHub b501ecc736 ENH: Adds support for supplementary asset mappings (#1612)
* ENH: Adds support for supplementary asset mappings

- Adds a supplementary_mappings table to the assets.db, to hold point-
  in-time mappings of sids to arbitrary categories of values, e.g.
  alternative identifiers. This bumps ASSET_DB_VERSION.

- Adds supplementary_map and supplementary_map_by_sid to AssetFinder,
  caches of the underlying table that are fully populated on first
  access, which map the supplementary values to sids and vice versa,
  respectively.

- Adds lookup_by_supplementary_mapping method, which fronts
  supplementary_map to query for the asset last known to have held a
  value at a given dt.

- Add get_supplementary_field method, which fronts
  supplementary_map_by_sid to query for the last known value held by an
  asset at a given dt.
2016-12-16 15:20:53 -05:00
Joe JevnikandJoe Jevnik de7c32b22c ENH: Allow custom chunks iterators for attach_pipeline 2016-12-15 19:58:19 -05:00
Ana RuelasandGitHub 1888cf595f Merge pull request #1611 from quantopian/fix-buildbreaking-docstring
DOCS: Minor (but build breaking) docstring fix
2016-12-06 14:26:48 -05:00
Ana Ruelas 3cfbdeaca1 DOCS: Minor (but build breaking) docstring fix 2016-12-06 13:33:22 -05:00
Eddie HebertandGitHub 0fa4031f97 Merge pull request #1610 from quantopian/allow-skips-across-contracts
BUG: Allow rolls to skip over contracts.
2016-12-05 22:53:36 -05:00
Eddie Hebert a19ec84a1d BUG: Allow rolls to skip over contracts.
For futures that behave like GC, use the latest roll as the back contract when
walking backwards over the window, so that when the front contract is skipped
because it never has more volume between its auto close date and the previous
auto close date, the back contract which did have volume is still used when
making comparisons to construct the chain.
2016-12-05 22:33:03 -05:00
Eddie HebertandGitHub b120da4a4c Merge pull request #1609 from quantopian/use-custom-business-day-for-session-loop-logic
MAINT: Use session index freq for loop logic.
2016-12-05 13:59:07 -05:00
Eddie Hebert 584ff4d67a MAINT: Use session index freq for loop logic.
Instead of maintaining a separate index into the sessions index, use the `.freq`
member of the sessions index for decrementing to the current session and finding
the previous session.
2016-12-05 13:08:49 -05:00
Eddie HebertandJoe Jevnik 583f347bc3 DOC: Update testpypi install command
When following the release guide, installing from testpypi using the
`-i` flag failed on my, and at least one other's, development machines.
The cause of the failure appears to be that pip would look for packages,
such as `LogBook` or `pandas` on `testpypi`. However many dependencies
do not have versions that meet our version criteria. (e.g. pandas does
not have a version between 0.16.0 and 0.18.0 on testpypi.)

Instead, use `--extra-index-url` so that other packages can use `pypi`
as a fallback server, instead of being limited to `testpypi`.
2016-12-01 14:40:38 -05:00
Joe JevnikandJoe Jevnik c1063eac26 BUG: fix blaze pipeline queries for asof_date 2016-12-01 14:35:59 -05:00
Eddie HebertandGitHub 3e1a518ae6 Merge pull request #1607 from quantopian/allow-delivery-subsets
ENH: Allow future chains to only use certain delivery months.
2016-12-01 14:06:32 -05:00
Eddie Hebert 1f71c8d068 ENH: Allow future chains to only use certain delivery months.
To support contracts such as `PL` which should roll from F->J->N->V, add the
ability to pass a predicate function to the ordered contract chain contstrution
which returns `True` if the contract is allowed in the chain.
2016-12-01 13:26:07 -05:00
Eddie HebertandGitHub 3575351306 Merge pull request #1606 from quantopian/fix-volume-rolls-with-adjustments
BUG: Fix 1m history for volume rolls with adjustments.
2016-11-30 14:24:02 -05:00
Eddie Hebert d217b275fb BUG: Fix 1m history for volume rolls with adjustments.
Convert the end minute to the its session label before calling `_active_contract`,
otherwise the volume roll finder's attempt to use the session bar reader fails
due to a non-session label Timestamp.
2016-11-30 13:13:53 -05:00
Eddie HebertandGitHub 726edb0e32 Merge pull request #1605 from quantopian/support-non-month-to-month-rolls
BUG: Support futures which do not roll month to month.
2016-11-30 12:47:16 -05:00
Eddie Hebert c3004b2529 BUG: Support futures which do not roll month to month.
Fix multiple errors when attempting to generate rolls for futures which do not
roll month to month, e.g. the Eurodollar.

These errors were caused by logic that always incremented from contract to
contract by delivery month, with errors when the next contract was not part of
the quarterly roll chain and thus had not yet begun trading even though the
previous contract had autoclosed. Instead, filter out these contracts and only
allow contracts that have begun trading before the previous contract's autoclose.

This is in lieu of a more explicit specification of quarterly rolls.
2016-11-30 11:23:43 -05:00
Eddie HebertandGitHub 69b35a131a Merge pull request #1604 from quantopian/use-linked-list-for-contracts
MAINT: Use a doubly linked list for contract chain.
2016-11-30 06:54:28 -05:00
Eddie Hebert 518f3d1f4b MAINT: Use a doubly linked list for contract chain.
Instead of requiring the roll finder to juggle the indices into the ordered
contracts, use a doubly linked list where the nodes element is the contract
with members pointing to the previous and next contracts in the chain.

Besides improving legibility in the roll finder code, this change is on the path
to adding a predicate to exclude contracts from the chain, e.g. contracts in ED
which are not in the roll schedule.

Change test results for primary chain, since new implementaton does not stop at
contract in which has not yet started when constructing the chain.
2016-11-30 06:01:59 -05:00
Scott SandersonandGitHub e5c941e592 Merge pull request #1588 from quantopian/randc-built-in-factors
ENH: Add MACD, MA, and AnnVol as built in factors
2016-11-28 16:18:58 -05:00
Scott SandersonandGitHub 9594d2779b Merge pull request #1603 from quantopian/randc-built-in-factors-twekas
Randc built in factors twekas
2016-11-28 15:30:40 -05:00
Scott Sanderson 399bf3085c DOC: Docstring updates. 2016-11-28 15:29:36 -05:00
Scott Sanderson 9c05e5edfe MAINT: Tweaks/cleanups in technical.py.
- Use `expect_bounded` to check inputs.
- Add tests for expected failures from `MACDSignal`.
- Use `float64` instead of `float` in a few places.  This prevents
  diverging behavior on 32-bit systems.
- Docstring edits.
2016-11-28 13:02:40 -05:00
Scott Sanderson 48327266db MAINT: Put exponential_weights where it's used.
`math_utils` is mostly a shim around bottleneck imports.  If we need
this somewhere else, it probably belongs in `numpy_utils`.
2016-11-28 13:02:40 -05:00
Scott Sanderson 5e8cc00625 STY: Put whitespace between operators. 2016-11-28 12:57:03 -05:00
Scott Sanderson 9b8d6202f0 TEST: Use parameter_space for randomized tests.
- Use a RandomState with a seed so that we have repeatible results.
- Use `randint` instead of `random_integers.` `random_integers` is
  deprecated.
- Use `parameter_space` to test multiple period lengths.
2016-11-28 12:57:03 -05:00
Scott SandersonandGitHub bd84338aca Merge pull request #1599 from quantopian/memory-savings
Memory savings
2016-11-28 10:52:23 -05:00
Eddie HebertandGitHub 5842e981d7 Merge pull request #1600 from quantopian/use-prev-session-for-volume-roll
BUG: Fix bounds errors in roll finder.
2016-11-26 21:37:21 -05:00
Andrew DanielsandGitHub adc9900860 MAINT: Improve minute writer handling of non-trading minutes (#1602)
Previously, if input to the BcolzMinuteBarWriter had the first bar on a
non-trading minute, the next trading session would be considered the
"first day" in the input. Now, we consider the previous trading session
the "first day".

The intention is to correctly associate minutes after official trading
hours on half days with session that closed early, not the following
session (a future improvement here would be to not accept minutes
outside trading hours).
2016-11-26 21:12:12 -05:00
Jonathan Kamens 96f8eeeb5f BLD: Use https to download ta-lib source 2016-11-25 12:12:33 -05:00
Ana Ruelas f1254ea79a ENH: Add MACDSignal, test with random input 2016-11-23 11:43:29 -05:00
Eddie Hebert 40605e3c5d BUG: Fix bounds errors in roll finder.
Fix common error condition which was triggered whenever the session at the end
of the prefetched history window was a session where the back contract was
active. When the back contract was the active contract, the next contract for
consideration was the front contract at the end of the window, which
definitionally always has an autoclose after the end of the window.
Instead, just start seeking backwards from the end of the window.

Also prevent lookahead bias in volume rolls, which was caused by the using the
volume for a session to determine whether that session had rolled. Information
that would not have been available at the beginning of the session.

This change makes the volume rolls overly conservative, and may be improved by
looking at vectors of the preceding volume and making the roll off of momentum.
2016-11-23 10:35:45 -05:00
Scott Sanderson aa3f2220d9 MAINT: Hit more dataframe indexers. 2016-11-22 17:11:04 -05:00
Scott Sanderson f244a20e65 BUG: sys.exc_clear is py2 only. 2016-11-22 16:34:53 -05:00
Scott Sanderson a60c9c683c MAINT: Use lazyval instead of two decorators. 2016-11-22 14:26:58 -05:00
Scott Sanderson b091b40604 PERF: Use searchsorted instead of get_loc.
On pandas < 18, `get_loc` triggers allocation of a large hash table, so
we don't want to call get_loc on minutely `DatetimeIndex`es.
2016-11-22 14:26:58 -05:00
Scott Sanderson ac8d21f1da PERF: Deterministically GC pipeline results.
Any DataFrame that's had `.loc` or `.iloc `called on it participates in
a cycle, which means they're not immediately garbage collected when they
go out of scope.  This matters for pipeline results because they consume
multiple megabytes per column, which means that a pipeline result with
many columns can hold take up over 100MB.  By manually breaking
DataFrame cycles, we can ensure that we never hold multiple pipeline
results in memory at once.
2016-11-22 14:26:58 -05:00
Andrew DanielsandGitHub d65af6c706 BUG: Ensure minute OHLC values can safely be converted to uint32 (#1598)
Otherwise, we either raise an exception or filter out all unsafe values.
This addresses an issue where the BcolzMinuteBarWriter would scale up
values to convert to uint32, but the resulting values were too large,
and would be mangled.

Based on the approach we take in the BcolzDailyBarWriter.
2016-11-22 14:11:43 -05:00
Ana Ruelas 9aa6a585c4 TST: Add test for annualized volatility factor 2016-11-21 14:24:28 -05:00
Ana Ruelas 66dd10a50c ENH: Actually use rolling windows for EWMA in MACD 2016-11-21 14:24:28 -05:00
Scott SandersonandAna Ruelas 72203280d2 MAINT: Use fancy default for window_length. 2016-11-21 14:24:28 -05:00
Ana Ruelas 735aaf1b27 ENH: Add MACD, MA, and AnnVol as built in factors 2016-11-21 14:24:19 -05:00
Maya TydykovandGitHub 6734eb2afb Merge pull request #1557 from quantopian/split_adjust_estimates
Split adjust estimates
2016-11-18 10:21:04 -05:00
Maya Tydykov bfc01546ae ENH: allow estimates to be split-adjusted.
This modificaiton to the estimates loader allows the caller to pass
in an equity pricing loader which can then be used to get split data
for sids. That split data is then used to do point-in-time adjustments
of estimates data.

TST: add test for multiple estimates columns

TST: add test for multiple datasets requesting different columns

TST: add blaze versions for all next/previous tests
2016-11-18 09:39:54 -05:00
Eddie HebertandGitHub a7a350d930 Merge pull request #1595 from quantopian/nan-check-transactinos
TMP: Add temporary fix for transactions with nan fill prices.
2016-11-17 13:10:32 -05:00
Eddie Hebert 613fdeab50 TMP: Add temporary fix for transactions with nan fill prices.
Protect a case where data is written with a non-zero volume, but a 0/nan for the
OHLC values. The slippage model was relying on a non-zero volume implying that
there was a valid trade price for the corresponding bar. When there was a mismatch,
a transaction with a nan value was created, which would in turn propagate the
nan into portfolio value, which would then cause errors when the portfolio value
was used to size orders during rebalancing.

When data is fixed, can remove.
(Also may want to add behavior to minute bar writer to ensure that 0 volumes
always have corresponding nan ohlc.)
2016-11-17 12:00:28 -05:00
Eddie HebertandGitHub 70b3055a68 Merge pull request #1594 from quantopian/fix-after-half-day-nan
BUG: Fix minute bar last traded after half day.
2016-11-15 15:33:42 -05:00
Eddie Hebert 5624e0f391 BUG: Fix minute bar last traded after half day.
When the following conditions occur,

- a `nan` occurred after a half day (e.g. on the Monday after
Thanksgiving, where the Friday would be a half day.)

-data was written to the span between the early close and where the market close
would have been if it were not an early close session

- a `nan` also occured on the last minute of the early market session.

the exisitng implementation would incorrectly return a `nan` when requesting a
forward filled price.

The steps that caused this error were.

1. Request for `'price'` on the market open of the day after the early close.

2. `nan` is found for that minute

3. `get_last_traded_dt` is called, and finds a volume that occurs after the
early close. e.g. `18:47` when the market close was `18:00`.

4. The minute position for `18:47` is used, when calling
`find_positon_of_minute`, since that value is after the `market_close` the
minute is set to the position of `18:00`` due to the delta logic in

5. Since there is also no data in at `18:00`, a `nan` is returned, even though
there were valid minutes earlier in the session. e.g. a non-zero volume at
`16:47` should have been used, but was not.

Fix by checking the current minute against the minute close when searching for
the last traded minute. If the minute is greater than the market close for the
corresponding day, continue the search until the minute position is within the
trading session.

This could also be fixed by enforcing that only zeros can be written between an
early close and the minute where the close would have been, but this fix allows
the reader to work with existing data.
2016-11-15 15:09:19 -05:00
Eddie HebertandGitHub 48324cf791 Merge pull request #1592 from quantopian/remove-duplicate-get-rolls
MAINT: Remove duplicate get_rolls in reader.
2016-11-14 15:43:27 -05:00
Richard Frank 3546dbd64d MAINT: Updated ta-lib source download urls to https 2016-11-14 12:34:19 -05:00
Richard FrankandGitHub be457b088c Merge pull request #1593 from quantopian/nicer-message
ENH: An improved error message when calling zipline api functions
2016-11-11 17:22:06 -05:00
Richard Frank a61de3a4e7 ENH: An improved error message when calling zipline api functions
outside of a running simulation. Previously, an AttributeError was
raised.
2016-11-11 17:00:03 -05:00
Eddie HebertandGitHub b9b9b7d32b Merge pull request #1590 from quantopian/speed-up-history-loader-creation
PERF: Speed up retrieval of HistoryLoader calendar.
2016-11-11 11:37:31 -05:00
Eddie Hebert 00ebae7729 MAINT: Remove duplicate get_rolls in reader.
The rolls are already calculated and assigned to `rolls_by_asset` earlier in the
`load_raw_arrays` method, so remove the duplication.

The change should not affect results.
2016-11-11 11:09:02 -05:00
Eddie Hebert 08fb7333d6 PERF: Speed up retrieval of HistoryLoader calendar.
The use of `slice_indexer` on all market minutes was taking about 110ms on my
development machine.

This change to getting the start and end indices changes the entire `_calendar`
method to take 10ms on the same machine.

Noticed while creating a `HistoryLoader` in a notebook context.
2016-11-11 10:54:07 -05:00
Richard FrankandGitHub 907f30d013 Merge pull request #1589 from quantopian/rotate-anaconda-token
Rotate anaconda token
2016-11-10 13:45:44 -05:00
Richard Frank 0145cf8bf0 SEC: Rotated anaconda token for travis 2016-11-10 12:12:02 -05:00
Richard Frank a4a571aff0 DOC: Added ANACONDA_TOKEN directions 2016-11-10 12:12:02 -05:00
Eddie HebertandGitHub b4692c4121 Merge pull request #1587 from quantopian/fix-bug-for-continuous-future-max-date
BUG: Fix continuous future end dates.
2016-11-09 16:41:57 -05:00
Eddie Hebert 48c360727b BUG: Fix continuous future end dates.
The end date of the last contract with a sufficient start date was being
used for the continuous future overall end date; however the end date of
that contract (which is the last day for which there is data for the
contract) is not necessarily the greatest end date out of all contracts.
It is possible for the furthest out contract to have some, but very
few, trades before it is more actively traded. Which would give it a
start date within in the range of the simulation, but an end date is
earlier than the other contracts which are active during the simulation.

This bug would result in `nan`s when getting the current price because
of the `end_date` check in `get_spot_value`. When the current simulation
time was greater than the `end_date` of the last contract the condition
which guards against attempting to get data for an instrument past its
end date would return a `nan`, even when the current underlying contract
did have data for that date.

Use max end date of all contracts instead of the last one, to ensure
that the continuous future last date is always great enough to allow
access to all contracts with in the chain.

Also, use min start date to accurately mirror the end date behavior.
2016-11-09 16:19:19 -05:00
Eddie HebertandGitHub dad709590d Merge pull request #1586 from quantopian/fix-continuous-future-daily-get-value
BUG: Fix bad attribute lookup on session continuous future reader.
2016-11-08 16:15:05 -05:00
Eddie Hebert 57d35f6aac BUG: Fix bad attribute lookup on session continuous future reader.
Use `roll_style` not `roll`.

Also, add test case to cover using the session bar reader `get_value`,
by adding a test which uses `close`, since only `contract` was being
exercised, which does not exercise the session daily bar reader.
2016-11-08 15:48:28 -05:00
Eddie HebertandGitHub 069058be3b Merge pull request #1585 from quantopian/pricing-data-associable
MAiNT: Add a pricing data shared abc.
2016-11-08 12:26:02 -05:00
Eddie Hebert 604f8dd96f MAiNT: Add a pricing data shared abc.
Register equities, futures, and continuous futures to an `abc` which
signifies that the type is associable with data, and thus can be used in
a history context.

May want to use this in `check_parameters` for `BarData` methods, but
work would need to be done to make sure the error message still displays
the registered types.
2016-11-08 11:36:45 -05:00
Eddie HebertandGitHub fc1f6aeae9 Merge pull request #1584 from quantopian/allow-single-continuous-future
BUG: Fix `data.history` with a single continuous future.
2016-11-08 11:33:57 -05:00
Eddie HebertandGitHub f7fdc56777 Merge pull request #1583 from quantopian/allow-sliding-window-to-reset
ENH: Allow arbitrary history queries.
2016-11-07 22:31:13 -05:00
Eddie Hebert 6ff1d55504 ENH: Allow arbitrary history queries.
In preparation for using `DataPortal` in notebooks, remove restriction on
the `HistoryLoader` to dates that are monotonically increasing. Notebook
usage of the `DataPortal` is more useful when the end of the history
window can be arbitrary dates without having to restart the notebook kernel.

Due to the implementation of the prefetch and caching logic, the end
date of history calls could previously only increase. e.g. `2016-11-01`,
`2016-11-02`, `2016-11-03`. This pattern was sufficient for backtesting
and live simulations, since the current time of the algorithm only ever increases.

With this change, which resets the underlying sliding window when the
last fetched idx is greater than the

Now calls to history in the same process with end dates such
`2016-11-01`, `2016-10-31`, `2015-11-02` should work.
2016-11-07 16:40:51 -05:00
Eddie Hebert 9e8212b25b BUG: Fix data.history with a single continuous future.
Allow `ContinuousFuture` when checking for a single "asset".

This could be further improved by:

- Defininng a tuple of the `Asset`-like types OR making
`ContinuousFuture` and `Asset` share a common type (whether that is
`ContinuousFuture` inheriting from `Asset` or making `Asset` and
`ContinuousFuture` share a common type.)

- Make a `history` test which uses `BarData` + `ContinuousFuture`,
instead of just using the history loader directly from tests.
2016-11-07 16:34:26 -05:00
Andrew DanielsandGitHub f94a161c7a BUG: Allows 'contract' in get_spot_value with daily frequency (#1582)
Also removes duplicate check in test_current_contract.
2016-11-07 16:28:48 -05:00
Eddie HebertandGitHub 2b925ecb78 Merge pull request #1581 from quantopian/import-style-on-calendars
STY: Add space between import and open parens.
2016-11-04 14:08:05 -04:00
Eddie HebertandGitHub 676fb9cb89 Merge pull request #1580 from quantopian/research-compatible-history-loader
ENH: Allow configurable history prefetch length.
2016-11-04 14:07:33 -04:00
Eddie Hebert 336867df15 STY: Add space between import and open parens.
For compliance with newer flake8 versions.

Should be no functional change.
2016-11-04 13:45:19 -04:00
Eddie Hebert a3df1e3cef ENH: Allow configurable history prefetch length.
To support using a `DataPortal` and `HistoryLoader` in a notebook, allow
the prefetch length to be configurable, so that it can be set to 0.
Unlike backtesting where the prefetch is useful for repeated history
windows viewed from datetimes which are monotonically increasing by a
small amount, the notebook usage of history windows needs only to
retrieve the exact data needed for the window specified.

This patch also fixes some boundary conditions related to rolls and
adjustments which were uncovered by querying for the adjustments with an
end date near the end of the window.
2016-11-04 13:30:30 -04:00
Andrew DanielsandGitHub a0e36d492d PERF: Use ctable.resize to speed up BcolzMinuteBarWriter.truncate (#1578)
This is significantly faster than the previous approach of writing a new
ctable with a slice of the existing table.
2016-11-04 10:31:41 -04:00
Scott SandersonandGitHub 1a13e6172f Merge pull request #1574 from quantopian/make-corrcoefs-window-safe
ENH: Mark statistical terms as window_safe.
2016-11-01 12:49:27 -04:00
Scott Sanderson 2c087ef77b ENH: Mark statistical terms as window_safe. 2016-11-01 12:16:34 -04:00
Scott SandersonandGitHub 2b6fbdc202 Merge pull request #1573 from quantopian/rename-specific-assets
MAINT: Rename `SpecificAssets` to `StaticAssets`.
2016-11-01 12:15:10 -04:00
Scott Sanderson 24931bd4dd MAINT: Rename SpecificAssets to StaticAssets.
This better reflects the intended usage of accepting a fixed set of
predetermined assets.
2016-11-01 11:01:36 -04:00
Joe JevnikandGitHub 62bb389199 BUG: load extensions in IPython magic (#1543) 2016-10-28 16:00:51 -04:00
Joe JevnikandGitHub 867b878c9a Merge pull request #1521 from quantopian/add-optimization-pass-for-initial-workspace
Add optimization pass for initial workspace
2016-10-28 15:42:52 -04:00
Scott SandersonandJohn Ricklefs 563a8b34f3 STY: Put 0 at the end. (#1569) 2016-10-28 15:14:22 -04:00
Joe Jevnik ad7ddd17ea STY: cleanup 2016-10-28 15:04:18 -04:00
Scott SandersonandJoe Jevnik 66a214fae9 ENH: Allow windows of NumericalExpression.
If all the inputs to an expr are window-safe, then the expr is itself
window-safe.
2016-10-28 15:04:18 -04:00
Scott SandersonandJoe Jevnik 0f57dac4ab TEST: Add more populate_initial_workspace tests.
- Tests different pipeline lengths and window lengths.
- Tests a term that depends on a window of a term that's been
  precomputed.
2016-10-28 15:04:18 -04:00
Joe Jevnik 7f40f7a99d STY: remove unused imports and method, clean up docs 2016-10-28 15:04:18 -04:00
Joe Jevnik d5b901df3f TST: add tests for postprocess and to_workspace_value 2016-10-28 15:04:18 -04:00
Joe Jevnik 9822ee5783 TST: add more dispatches 2016-10-28 15:04:18 -04:00
Joe Jevnik 0eb461bd16 ENH: cleanup branch based on feedback 2016-10-28 15:04:18 -04:00
Joe Jevnik 92516e6609 ENH: prune the graph based on the initial workspace 2016-10-28 15:04:18 -04:00
Joe Jevnik 499680553f ENH: update aliasedmixin repr 2016-10-28 15:04:18 -04:00
Joe Jevnik f9ce7f060e ENH: Make aliases filters, factors, and classifiers to give them their methods 2016-10-28 15:04:18 -04:00
Scott SandersonandJoe Jevnik 7fc2588571 WIP: Add Alias expression. 2016-10-28 15:04:18 -04:00
Joe Jevnik 4f9c6bd254 ENH: provide a hook for prepopulating the initial workspace 2016-10-28 15:04:18 -04:00
Joe Jevnik 892b7cca00 ENH: Provide methods to undo the 'postprocess' step in computing pipeline output 2016-10-28 15:04:18 -04:00
Scott SandersonandGitHub 9f10bbaf94 Merge pull request #1568 from quantopian/fix-microoptimizations
Fix microoptimizations
2016-10-28 14:57:43 -04:00
Scott Sanderson e89410dc30 MAINT: Consolidate data_portal names.
Rename _get_daily_window_for_sids to _get_daily_window_data.
Rename _get_minute_window_for_assets to _get_minute_window_data.
Rename _get_daily_data to get_daily_spot_value.
2016-10-28 14:35:05 -04:00
Scott Sanderson 8ccdb48c40 DOC: Comment on outdated code. 2016-10-28 14:06:35 -04:00
Scott Sanderson b714a23b44 BUG: Raise SidsNotFound in retrieve_asset. 2016-10-28 14:05:49 -04:00
Richard FrankandGitHub 7e505926b6 Merge pull request #1567 from bernoullio/master
MAINT: Restore @property decorator
2016-10-28 12:10:58 -04:00
keang 914dca1685 MAINT: Restore @property decorator
This will keep `opens`, `closes`, `early_closes`, etc to the
same pattern.
2016-10-28 23:25:53 +08:00
Scott SandersonandGitHub ac74a9dff5 Merge pull request #1561 from quantopian/micro-optimizations-2
Micro optimizations 2
2016-10-28 10:36:33 -04:00
Eddie HebertandGitHub e93087e452 Merge pull request #1565 from quantopian/fix-offset-history
BUG: Fix continuous future history with offsets.
2016-10-28 09:44:34 -04:00
Eddie HebertandAndrew Daniels 8876092d29 BUG: Protect against contract offset at end of range. (#1564)
This boundary case was exposed with internal fixture data which used a
continuous future with a contract chain of size one.
2016-10-27 16:48:34 -04:00
Eddie Hebert c25da8f442 BUG: Fix continuous future history with offsets.
Apply offset value when writing out the rolls in a continuous future
which is offset from the primary.
2016-10-27 16:23:03 -04:00
Eddie HebertandGitHub e07d5a202a Merge pull request #1563 from quantopian/use-same-session-for-contract-closes
BUG: Use proxy for settlement on future adjustments.
2016-10-27 13:31:12 -04:00
Eddie Hebert e1bafe1ecc BUG: Use proxy for settlement on future adjustments.
Instead of using the difference between the session close of the front
contract before the roll and and the open of back contract on the
beginning of the roll, use the close of both at the end of the session
before the roll.

The closes of the session prior to roll is in lieu of settlement data.
2016-10-27 12:40:59 -04:00
Scott Sanderson 48c725b5ea PERF: Call concatenate directly instead of hstack.
Avoids a couple function calls in a hot path.
2016-10-26 23:49:48 -04:00
Scott Sanderson 0cbc2ca388 PERF: Don't round until after we hstack. 2016-10-26 23:30:12 -04:00
Scott Sanderson 1e889987eb MAINT/PERF: Remove redundant method call.
`_get_minute_window_data` was just forwarding its input to a method with
the same signature.
2016-10-26 23:28:34 -04:00
Scott Sanderson d18080553b PERF: Pull out loop-invariant code.
This shaves off 20 out of 160 seconds for an algorithm that makes a
large number of large universe, short window_length `history()` calls.
2016-10-26 23:27:33 -04:00
Scott Sanderson 16e3cb50cc PERF: Use vectorized assignment into dataframe.
This is a dramatic speedup (~25% in local benchmarks) for history calls
with a large number of assets and a short window length.
2016-10-26 21:10:40 -04:00
Paul SutherlandandJoe Jevnik 0fbf7b428b DEV delete old *.c and *.so files with rebuild-cython.sh for Darwin/OSX (#1560) 2016-10-26 19:08:36 -04:00
Scott Sanderson a252bb1e3f PERF: Refactor AdjustedArrayWindow.
Make `__next__` and `seek` share code instead of seek() calling
`__next__`.  This avoids having to make a large number of integer
comparisons and `asanyarray` calls when seeking more than one tick
forward.
2016-10-26 17:32:27 -04:00
Scott Sanderson 57a0822b60 BUG: Return NaT instead of None in daily reader. 2016-10-26 17:32:27 -04:00
Scott Sanderson 52b71af848 PERF: Vectorize assignments in get_history_window. 2016-10-26 17:32:27 -04:00
Scott Sanderson fc153999e2 PERF: Remove attribute access in inner loop. 2016-10-26 17:32:27 -04:00
Scott Sanderson a1f771c1fa MAINT: Auto-rebuild templated cython files. 2016-10-26 16:44:07 -04:00
Scott Sanderson eb2b10554b PERF: Try cache on scalar asset lookups.
This provides a 15% speedup for an algo that calls `data.current` with
1000 every minute.
2016-10-26 15:22:28 -04:00
Eddie HebertandGitHub 82cbac85c2 Merge pull request #1558 from quantopian/add-detail-to-history-calendar-mismatch
MAINT: Add more info to history calendar KeyError.
2016-10-26 15:12:08 -04:00
Eddie Hebert 9294e39ea0 MAINT: Add more info to history calendar KeyError.
There have been cases where the requested start or end date is not in
the history calendar.

Add the beginning and of the calendar to the KeyError to give more
detail to figure out root cause.
2016-10-26 14:41:37 -04:00
Eddie HebertandGitHub 642e404982 Merge pull request #1556 from quantopian/volume-based-rolls
ENH: Volume based rolls for futures.
2016-10-25 15:21:41 -04:00
Eddie Hebert 473c8fddba ENH: Volume based rolls for futures.
Add roll style which takes the volume of the contracts into account.
If the volume moves from the front to the back before the auto close
date, the roll is put at that session.

Also, factors out some of the common logic shared with calendar based rolls.
2016-10-25 14:08:21 -04:00
Eddie HebertandGitHub 7e3e00c772 Merge pull request #1555 from quantopian/return-nan-from-bcolz-daily-reader
MAINT: Return nan from daily bcolz get_value.
2016-10-25 11:49:51 -04:00
Eddie Hebert a823cceabc MAINT: Return nan from daily bcolz get_value.
Match the behavior of the minute bar reader, now that the session and
minute bar readers share a common interface.

isnull is slightly slower than checking against -1; however, n cases
where we check against illiquid trades in a tight loop, volume is
checked which is not using nan. The change here should be marginal with
regards to performance.
2016-10-25 11:25:09 -04:00
Eddie HebertandGitHub 426c2070c8 Merge pull request #1553 from quantopian/change-start-date-of-cf-tests
TST: Make test dates aligned with test data.
2016-10-25 11:16:07 -04:00
Eddie Hebert fa63fa6dd5 TST: Make test dates aligned with test data.
Move dates queried near beginning of test data so that the range of data
covered does not extend beyond the beginning of the range.
i.e. the windows were covering 2016-01-25, which had no test data generated.
(Does not matter for the calendar based rolls, but is needed for volume
based rolls.)

Also, make room for having the first roll to be a day before the first auto
close by moving the first contracts auto close date back a day.

In preparation for testing volume rolls.
2016-10-25 10:21:23 -04:00
Eddie HebertandGitHub 3f85140bf9 Merge pull request #1552 from quantopian/fix-session-last-traded
BUG: Fix session from minute reader's last traded.
2016-10-24 14:21:15 -04:00
Eddie Hebert 18096f750a BUG: Fix session from minute reader's last traded.
The last traded dt provided from the session bar reader which resamples
from minutes should provide a dt that is a session label, not one that
is at the minute frequency.
2016-10-24 13:58:58 -04:00
Eddie HebertandGitHub 546cb138ec Merge pull request #1551 from quantopian/prevent-occlusion-of-key-error-in-history
MAINT: Prevent hiding of KeyError in adjustments.
2016-10-24 12:05:22 -04:00
Eddie Hebert 202b557c48 MAINT: Prevent hiding of KeyError in adjustments.
If a KeyError occurred in the adjustment logic, the exception would be
swallowed by the try block, which was intended to just check whether or
not there was an adjustment reader adjusted.

Discovered when some logic in a futures adjustment reader were failing
because of a mismatch of minute and session labels, which resulted in no
adjustments during windows when there should have been.
2016-10-24 11:33:00 -04:00
Eddie HebertandGitHub 0d10a20551 Merge pull request #1549 from quantopian/speedup-resample
PERF: Speedup minute to session sampling.
2016-10-24 10:25:51 -04:00
Eddie Hebert e82fef41dd PERF: Speedup minute to session sampling.
The minute to session sampling reading was creating two DataFrame
objects, the first to hold the minute data, and then a second returned
by the `DataFrame.groupby` to sample down to sessions.

Instead use the arrays returned by the minute readers `load_raw_arrays`
and implement sampling logic which takes advantage that the minutes
being passed start with the first minute of the first session and end
with the last minute of the last session.

On my machine this takes the tests in `test/test_continuous_futures`
from ~4.0 to about ~0.1 seconds.
2016-10-24 09:59:22 -04:00
Maya TydykovandGitHub eff2428068 Merge pull request #1547 from quantopian/fix-asset-selection-bug
BUG: create adjustments based on ordered assets instead of set
2016-10-24 08:56:19 -04:00
Maya Tydykov 086ea6be6b TST: update adjustment tests - add gaps between sids
TST: add a seed for permuting
2016-10-21 16:53:56 -04:00
Maya Tydykov 4ea60c2843 BUG: pass the entire list of assets 2016-10-21 16:23:38 -04:00
Maya Tydykov 5e5339285f BUG: create adjustments based on ordered assets instead of set 2016-10-21 16:23:38 -04:00
Eddie HebertandGitHub 71d6aa7a15 Merge pull request #1548 from quantopian/continuous-future-adjusted-history
ENH: Add adjusted history for continuous futures.
2016-10-21 11:22:54 -04:00
Eddie Hebert ce37ea64a9 ENH: Add adjusted history for continuous futures.
Add `.adj('mul')` and `.adj('add')` methods on ContinuousFuture, which
when used with `history`, will calculate and apply adjustments so that
the values are adjusted to account for discounts and premiums during
rolls.

Example usage in an algo:

```
from zipline.api import continuous_future

def initialize(context):
    context.cl_add = continuous_future('CL', offset=0, roll='calendar').adj('add')
    context.cl_mul = continuous_future('CL', offset=0, roll='calendar').adj('mul')
    context.cl = continuous_future('CL', offset=0, roll='calendar')
    schedule_function(print_history)

def print_history(context, data):
    frame = data.history([context.cl, context.cl_add, context.cl_mul],
                         ['price', 'sid'],
                         20,
                         '1d')
    print 'unadjusted'
    print frame.loc[:, :, context.cl]
    print 'adjusted add'
    print frame.loc[:, :, context.cl_add]
    print 'adjusted mul'
    print frame.loc[:, :, context.cl_mul]
```
2016-10-21 10:18:12 -04:00
Eddie HebertandGitHub bf7fdd9685 Merge pull request #1546 from quantopian/change-test-minute-markers
TST: Encode minutes in continuous future tests.
2016-10-19 13:28:27 -04:00
Eddie Hebert 9011d7b834 TST: Encode minutes in continuous future tests.
Include minutes (in addition to the days) in the price encoding for
continuous futures tests.

Need for different values minute to minute arose when working on tests
for adjusted values.
2016-10-19 11:40:53 -04:00
Eddie HebertandGitHub 6efe8e7edc Merge pull request #1544 from quantopian/remove-unused-adjustment-param
MAINT: Remove unused parameter.
2016-10-18 10:38:29 -04:00
Eddie Hebert ea749b081f MAINT: Remove unused parameter.
Was left in as an artifact of development branch.
2016-10-17 17:04:10 -04:00
Eddie HebertandGitHub e4150ca966 Merge pull request #1519 from quantopian/shimmed-load-adjustments
MAINT: Begin making a common adjustment interface.
2016-10-17 16:50:37 -04:00
Eddie Hebert 3d7d2c139b MAINT: Begin making a common adjustment interface.
Start making the equity adjustments calculations for the history loader
conform to the same method signature as `load_adjustments` provided by
`SQLiteAdjustmentReader, so that an `AdjustmentReader` interface can
begin to take form.

This prepares for creating a `DispatchAdjustmentReader` which will route
adjustment calculations for equities to the
`HistoryCompatibleUSEquityAdjustmentReader` and continuous futures to a
not yet implemented adjustment reader. All of these readers will share
the `load_adjustments` method.
2016-10-17 16:29:33 -04:00
Eddie HebertandGitHub 71765dd3f4 Merge pull request #1522 from quantopian/adjusted-array-perspective-offset
MAINT: Perspective offset for load adjustments.
2016-10-17 16:10:40 -04:00
Eddie Hebert 7d8768e2e4 MAINT: Limit perspective offset.
Limit the perspective offset to 1. There is a possibility that if a
consumer of the AdjustedArrayWindow does not fetch adjustments between
the end of the data window and the vantage points beyond the end of the
window.

Until that case has a solution, e.g. having the consumer of the
AdjustedArrayWindow include the perspective offset when calculating the
query for adjustments, limit the offsets to 1.
2016-10-17 15:08:11 -04:00
Scott SandersonandEddie Hebert 62f24dcad7 MAINT: Alternate AdjustedArray boundary conditions.
Avoids the need for a special sentinel value, and means that we only
have to have one branch instead of two in the inner loop.
2016-10-17 14:23:39 -04:00
Scott SandersonandEddie Hebert ce223db78c DOC: Fix typo in comment. 2016-10-17 14:23:39 -04:00
Scott SandersonandEddie Hebert 68ffd694e3 MAINT: Use perspective_offset in more tests.
- Refactor `test_adjusted_array` to test a range of perspective_offsets in
  all tests.

- Make perspective_offset a parameter to `AdjustedArray.traverse`
  instead of `AdjustedArray`.
2016-10-17 14:23:39 -04:00
Eddie Hebert 34d4e4b974 MAINT: Perspective offset for load adjustments.
Add a perspective offset to `AdjustedArrayWindow` and `AdjustedArray`,
so that `HistoryLoader` does not need to twiddle with offsets to support
viewing the data from the bar after end of the window, (Which is the
case when a '1d' history window is retrieved in minute mode, which is
explained in the docstring for `HistoryLoader.history`)

Presently, this simplifies the logic in
`HistoryLoader._get_adjustments_in_range`, and other incoming
AdjustmentReader's, (e.g. the roll based adjustment reader for continous
futures.) This patch should also make it easier for history and pipeline
to converge on a singular `load_adjustments` method.
2016-10-17 14:23:39 -04:00
Eddie HebertandGitHub 837d8824de Merge pull request #1539 from quantopian/continuous-future-history
ENH: Add history for continuous futures.
2016-10-16 23:14:08 -04:00
Eddie Hebert 2f16c08dcd ENH: Add history for continuous futures.
Enable unadjusted history for continuous futures.

The history array is filled by the values for the underlying contracts,
where the contract used changes based on rolls.

e.g., if a `1d` history window was over the range
`2016-01-20` -> `2016-02-29` with contracts with a suffix of `F16` that
rolls at the beginning of the session on `2016-01-26`, `G16` on
`2016-02-26`, and `H16` on `2016-03-26`. The `2016-01-20` ->
`2016-01-25` portion would use the values for `F16', the `2016-01-26` ->
`2016-02-25` portion would use `G16` and the `2016-02-26` ->
`2016-02-29` portion would use `H16`.

Using the same contracts as above, a `1m` history window over the range
(using a timezone of US/Eastern) `2016-01-25 4:00PM` -> `2016-01-25
7:00PM` would fill the `4:00PM` -> `6:00PM` portion with data for `F16`
and the `6:01PM` -> `7:00PM` portion with data for `G16`, since the
beginning of the `2016-01-26` session is `2016-01-25 6:01PM`.

Supports `1d` and `1m`.

Also adds the `sid` field to `history` to assist in showing the active
contract at each dt in the window.
2016-10-16 22:40:08 -04:00
Joe JevnikandGitHub 3f8a86dbb5 Merge pull request #1538 from quantopian/events-loader-query-fix
fix events loader blaze query
2016-10-13 15:49:57 -04:00
Joe Jevnik 95a56663d0 BUG: fix blaze query in ffill_query_in_range to correct issue in events loader 2016-10-13 15:27:44 -04:00
Scott SandersonandGitHub 8f85bef9fe Merge pull request #1537 from quantopian/allow-partials-in-assert-equal
BUG: Allow partials in assert_equal.
2016-10-12 19:28:35 -04:00
Scott Sanderson e1b8f34182 BUG: Allow partials in assert_equal. 2016-10-12 19:06:56 -04:00
Scott SandersonandGitHub 103993a8a8 Merge pull request #1536 from quantopian/allow-name-override-in-preprocessors
ENH: Name overrides in preprocessor factories.
2016-10-12 17:00:56 -04:00
Scott Sanderson cdfad2a54f ENH: Name overrides in preprocessor factories.
Allows ``__funcname`` to be passed to preprocessors like expect_types
and expect_dtypes to override the name displayed in error messages.
This is useful for providing clearer errors for ``__init__`` and
``__new__`` methods in classes.
2016-10-12 15:50:10 -04:00
Maya TydykovandGitHub 047313b516 Merge pull request #1535 from quantopian/small-updates-for-estimates
MAINT: small updates to fix deprecation warnings
2016-10-12 14:41:51 -04:00
Maya Tydykov e52d831a94 MAINT: small updates to fix deprecation warnings 2016-10-12 14:21:11 -04:00
Scott SandersonandGitHub 81b7d5eadc Merge pull request #1534 from quantopian/allow-kwargs-to-assert-equal-for-pandas-stuff
BUG/TEST: Forward kwargs to assert_series_equal.
2016-10-12 14:16:07 -04:00
Scott Sanderson dcf3124d26 BUG/TEST: Forward kwargs to assert_series_equal. 2016-10-11 21:29:41 -04:00
Eddie HebertandGitHub 7883f1fc06 Merge pull request #1533 from quantopian/current-chain
ENH: Add current chain for continuous futures.
2016-10-11 16:37:09 -04:00
Eddie Hebert c25b3d93f4 ENH: Add current chain for continuous futures.
Add `chain`field to current, as well as supporting methods in DataPortal
and OrderedContracts.

Enables the following example:

```
from zipline.api import continuous_future

def initialize(context):
    context.primary_cl = continuous_future('CL', offset=0, roll='calendar')
    schedule_function(print_current_chain)

def print_current_chain(context, data):
    chain = data.current_chain(context.primary_cl)
    print 'datetime={0}'.format(get_datetime())
    print 'primary={0}'.format(chain[0])
    print 'secondary={0}'.format(chain[1])
    print 'tertiary={0}'.format(chain[2])
```

```
datetime=2015-12-23 14:31:00+00:00
primary=Future(1058201602 [CLG16])
secondary=Future(1058201603 [CLH16])
tertiary=Future(1058201604 [CLJ16])
```

Also:
- make return types of OrderedContracts methods compatible across
architectures. (Noticed while adding `active_chain` method.)
- Add year suffix to future contract names in test data.
2016-10-11 16:16:16 -04:00
Joe JevnikandGitHub 70bd8e5f64 Merge pull request #1531 from quantopian/assert-slice-equal
TST: Adds assert_equal dispatch for slices
2016-10-11 11:14:23 -04:00
Maya TydykovandGitHub c0380f9d9b Merge pull request #1525 from quantopian/fix_estimates_overwrites_bug
Fix estimates overwrites bug
2016-10-10 09:02:40 -04:00
Maya Tydykov ea5b2b030c TST: add test condition to check for bug 2016-10-10 08:41:02 -04:00
Richard Frank 4c40d25be4 DOC: Updated example notebook for latest zipline cell magic 2016-10-09 22:12:20 -04:00
Scott SandersonandGitHub 7252a03d67 Merge pull request #1530 from quantopian/add-specific-assets
ENH: Add `SpecificAssets` filter.
2016-10-09 14:09:14 -04:00
Scott Sanderson 2a28f302ef DOC: Add a sentence with uses for SpecificAssets. 2016-10-09 13:41:10 -04:00
Scott Sanderson 58dca08d8b STY: Remove unused imports. 2016-10-09 13:18:18 -04:00
Scott Sanderson 1d5f3572c9 MAINT: Just require an iterable of assets. 2016-10-09 12:36:52 -04:00
Eddie HebertandGitHub fea7d899cd Merge pull request #1529 from quantopian/current-contract
ENH: Add continuous future current contract.
2016-10-07 23:39:01 -04:00
Joe Jevnik ee3c51f667 TST: Adds assert_equal dispatch for slices 2016-10-07 18:57:05 -04:00
Eddie Hebert fcf3e50cde ENH: Add continuous future current contract.
Add the ability for an algorithm to request the current contract for a
future chain via `data.current`.

e.g.:
```
data.current(ContinuousFuture('CL', offset=0, roll='calendar'),
'contract')
```
2016-10-07 18:26:23 -04:00
Scott Sanderson c9ebf9f45d ENH: Add SpecificAssets filter.
Adds a filter that matches a set of assets.  Mainly useful for testing
and debugging.
2016-10-07 18:11:01 -04:00
Andrew DanielsandGitHub 2f097ead76 ENH: Adds last_available_{session, minute} args to DataPortal (#1528)
This allows optionally setting the last available dts in the DataPortal
explicitly. If these args aren't provided, we fall back to inferring
these from the underlying readers, which was the previous behavior.
2016-10-06 20:46:54 -04:00
Andrew LiangandGitHub b6f8a67aad Merge pull request #1527 from quantopian/fix_restrictions
BUG: Restrictions passed into HistoricalRestrictions not sorted correctly
2016-10-05 15:02:50 -04:00
Scott Sanderson f3f138c450 TEST: Simplify testing of restriction orderings. 2016-10-05 14:42:17 -04:00
Andrew Liang e421a811e7 BUG: Restrictions passed into HistoricalRestrictions not sorted correctly 2016-10-05 14:09:26 -04:00
Ana RuelasandGitHub 6eafdddb39 Merge pull request #1524 from quantopian/empyrical-bump
ENH: Empyrical bump
2016-10-05 13:25:32 -04:00
Ana Ruelas 1bc55401b4 ENH: Empyrical bump 2016-10-05 12:54:16 -04:00
Maya Tydykov e304786fa0 BUG: append overwrites to list rather than replacing with new list 2016-10-05 12:47:25 -04:00
Eddie HebertandGitHub f92b6afb31 Merge pull request #1523 from quantopian/dispatch-reader-passes-asset
MAINT: Pass through asset instead of sid.
2016-10-04 15:01:48 -04:00
Eddie Hebert 5d9d9a97f5 MAINT: Pass through asset instead of sid.
When dispatching to sub readers in dispatch reader, pass along the asset
object, instead of extracting the sid.

The in development reader for continuous futures values besides `sid`
are needed from the `ContinuousFuture` object.
2016-10-04 14:39:23 -04:00
Scott SandersonandGitHub 1753a1ca3b Merge pull request #1518 from quantopian/add-coerce_types
MAINT: Add kwarg-based helper for coerce.
2016-10-03 19:52:08 -04:00
Andrew LiangandGitHub 4618303d36 Merge pull request #1487 from quantopian/rlist
Create in-memory restricted list
2016-10-03 16:01:39 -04:00
Scott Sanderson 50b65f1a77 MAINT: Add kwarg-based helper for coerce. 2016-10-03 13:12:52 -04:00
Andrew Liang 7a08dd6bed DOC: Clean up Restrictions documentation 2016-09-30 16:35:24 -04:00
Andrew Liang 25ba4369c3 ENH: _UnionRestrictions for combining multiple Restrictions 2016-09-30 16:35:24 -04:00
Andrew Liang 148d2a5273 MAINT: Rename restrictions.py to asset_restrictions.py
For clarity as to what sort of restrictions these are
2016-09-30 16:35:24 -04:00
Scott SandersonandAndrew Liang 73f1ac6255 STY: Remove extra whitespace. 2016-09-30 16:35:24 -04:00
Scott SandersonandAndrew Liang 9f4f19524a DOC: Fix docstring typo. 2016-09-30 16:35:24 -04:00
Scott SandersonandAndrew Liang 2a92b892ed BUG: days_at_time should return UTC dates.
Adds an example and clarifies the docs.
2016-09-30 16:35:24 -04:00
Scott SandersonandAndrew Liang 761ea7e417 MAINT: Use Timedelta instead of DateOffset.
In days_at_time, use a Timedelta instead of a DateOffset.  We were
previously using DateOffset to work around a pandas 16 bug even though
it raises a PerformanceWarning.  Now that we're on pandas 18, we can use
the much simpler Timedelta construction.
2016-09-30 16:35:23 -04:00
Scott SandersonandAndrew Liang 117450a489 DOC: Rename NoopRestrictions to NoRestrictions. 2016-09-30 16:35:23 -04:00
Scott SandersonandAndrew Liang d79c43a46a DOC: Update docstring for set_restrictions. 2016-09-30 16:35:23 -04:00
Scott SandersonandAndrew Liang 8f150eb6ce TEST: Clarify test_restrictions a bit.
- Use parameter_space instead of `parameterized.expand`.
- Use a timedelta instead of concatenating strings.
- Use a (possibly no-op) scramble function instead of reordering list
  literals.
- Use `freeze_dt, unfreeze_dt, re_freeze_dt` instead of `dts[n]`.
- Rename `assert_vectorized_results` to `assert_all_restrictions`.
2016-09-30 16:35:23 -04:00
Andrew Liang 99f6ecab3f MAINT: Deprecate set_do_not_order_list
In favor of a new method `set_restrictions` which takes a Restrictions
object. Calls to `set_do_not_order_list` should raise a deprecation
warning and create an equivalent Restrictions object, with which
`set_restrictions` will be called. For convenience, create a
RestrictionsSet from which the "restrictions" version of a security
list can be accessed
2016-09-30 16:35:23 -04:00
Andrew Liang a30f48e218 TEST: Modify tests for extra BarData parameter
Introducing a WithCreateBarData fixture which allows for the
creation of a BarData using only the `simulation_dt_func` and
`restrictions` params. Assumes that each suite uses the same
`data_portal`, `data_frequency` and `trading_calendar`
2016-09-29 10:11:15 -04:00
Andrew Liang af85b22313 MAINT: Create SecurityListRestrictions that takes a SecurityList
The SecurityList implements a non-exposed method
`current_securities(dt)` which SecurityListRestrictions calls to
determine if an asset is restricted. Deprecate the `__iter__` and
`__contains__` methods of security lists in favor of
`current_securities(dt)`
2016-09-29 10:11:14 -04:00
Andrew Liang b504d29a78 ENH: can_trade should take restricted list into account
Additionally, create an option for a violation of a 'do not order'
trading control to log an error instead of failing
2016-09-29 10:11:14 -04:00
Andrew Liang 0f47cf313d ENH: A point-in-time restricted list with restrictions stored in memory
An ABC Restrictions defines a group of restrictions responsible
for returning restriction information for sids on certain dts. An
InMemoryRestrictions is a point-in-time group of such restrictions,
with all restrictions and their dates passed in upon instantiation.
A StaticRestrictedList takes a list of sids, restricting them at all
dates
2016-09-27 18:19:51 -04:00
Maya TydykovandGitHub 60b736b594 Merge pull request #1396 from quantopian/add_estimates_quarter_loader_to_pipeline
Add estimates quarter loader to pipeline
2016-09-27 17:18:16 -04:00
Maya Tydykov 6cb06ffcdf TST: add test for changing event dates and adjustments
BUG: get column names from column dict

BUG: fix name map
2016-09-27 16:53:36 -04:00
Scott SandersonandGitHub 9e6509daa3 Merge pull request #1514 from fzagarzazu/fix-dockerfile
Docker build failure - Add Tini and set version range for numpy
2016-09-27 12:18:17 -04:00
Joe JevnikandMaya Tydykov 5d7100542c PERF: only query for the columns requested + metadata
BUG: choose last event date for quarter shift
2016-09-27 09:54:46 -04:00
Joe JevnikandMaya Tydykov 25b38520fa PERF: vectorize earnings estimates 2016-09-27 09:54:46 -04:00
Maya Tydykov cbd9bd068c TST: add test for sid with no data
MAINT: optimization - only look at assets appearing in data

TST: simplify test

DOC: add documentation for checkpoints

MAINT: explicitly cast event date field to datetime

MAINT: add back import

TST: fix indexing to remove setting wtih copy warning
2016-09-27 09:54:44 -04:00
Maya Tydykov 8d8f057120 MAINT: add checkpointing
BUG: add cols for sids with no data and get adjustments outside column loop
2016-09-27 09:54:43 -04:00
Maya Tydykov 7d75615fd2 TST: add test for missing num_quarters and clean up tests 2016-09-27 09:54:43 -04:00
Maya Tydykov 5e1a8224cd TST: add test to check previous columns w/ multiple qtrs
MAINT: pass column to name dict

MAINT: make check for invalid num columns py3-compatible
2016-09-27 09:54:41 -04:00
Maya Tydykov ebcc5f714a TST: add test for requesting multiple datasets with multiple quarters 2016-09-27 09:54:41 -04:00
Maya Tydykov eb22f2ab6b TST: add test for datetime array and update test
TST: fix quarter normalization test

TST: change test name

BUG: remove arg

BUG: look at dict keys

TST: add test for windowing

MAINT: raise ValueError instead of asserting

TST: add assertion to check windowing

TST: parametrize test over number of quarters forward/back.

BUG: fix adjustment calculation logic for quarter crossovers.

TST: add test for previous quarter windows

BUG: fix bugs in calculating previous windows

BUG: fix missing value for datetime

TST: add test case for missing quarter
2016-09-27 09:54:41 -04:00
Maya Tydykov af718b0f4a ENH: add adjustment for datetime64 arrays
BUG: fix adjustment start index
2016-09-27 09:54:40 -04:00
Maya Tydykov 2fb7ec7612 TST: add test for 1d array overwrite 2016-09-27 09:54:40 -04:00
Maya Tydykov 9ce4077cc6 ENH: add an adjustment for float64 2d arrays.
BUG: fix syntax error

MAINT: optimize code for cython
2016-09-27 09:54:39 -04:00
Maya Tydykov ef350f3889 TST: add cases for shifting release dates
BUG: fix bugs in blaze loader

BUG: call correct method

MAINT: explicitly cast dates column

MAINT: modify code to comply with pandas 0.16.1
2016-09-27 09:54:38 -04:00
Maya Tydykov f1c07708cd TST: add tests for quarter rotation logic 2016-09-27 09:54:37 -04:00
Maya Tydykov afc5297fe3 TST: add tests for quarter estimates
MAINT: modify algorithm for calculating previous releases

BUG: fix quarter calculation logic
2016-09-27 09:54:36 -04:00
Maya Tydykov 1c375806e7 ENH: add loader for estimates 2016-09-27 09:45:12 -04:00
Federico M. Zagarzazu de4d26cfd5 Set scipy and pandas version range in Dockerfile 2016-09-26 21:13:35 -05:00
Scott SandersonandGitHub 8ec76d4f38 Merge pull request #1513 from jkleint/patch-1
Propagate exceptions in loader to prevent variable reference before use
2016-09-26 10:36:03 -04:00
Federico M. Zagarzazu 3f078d4ef6 Add Tini and set version range for numpy in Dockerfile 2016-09-25 00:27:55 -05:00
jkleintandGitHub 82273e296f Propagate exceptions in loader to prevent variable reference before use
`data.loader.ensure_benchmark_data()` was trying to use data after an exception was raised loading it.  The code was logging and swallowing exceptions; this re-raises.
2016-09-23 15:55:55 -07:00
Andrew DanielsandGitHub db0eabe82a PERF: Replace get_loc calls in calc_dividend_ratios with get_indexer (#1510)
We can make a single vectorized call outside of the loop, instead of
repeatedly calling get_loc inside it.
2016-09-22 19:05:43 -04:00
Scott SandersonandGitHub 171736f2de Merge pull request #1508 from quantopian/forward-window-safety-in-demean
BUG: F.window_safe implies f.demean().window_safe.
2016-09-22 13:50:30 -04:00
Scott Sanderson bddb453272 BUG: F.window_safe implies f.demean().window_safe. 2016-09-22 12:41:50 -04:00
Andrew DanielsandGitHub f1919dc3af BUG: Makes NoData{Before, After}Date subclass NoDataOnDate (#1507)
This allows us to catch and handle all three of these exceptions in
`calc_dividend_ratios`.
2016-09-22 11:43:43 -04:00
Andrew DanielsandGitHub a5c7e93540 Merge pull request #1500 from quantopian/make-metadata-optional
MAINT: Adds option for minute bar writer to not write metadata
2016-09-21 12:40:19 -04:00
Eddie HebertandGitHub 25517e2b15 Merge pull request #1502 from quantopian/remove-future-chain
MAINT: Remove `future_chain` API method.
2016-09-21 11:44:57 -04:00
Andrew Daniels 96cc6b6588 MAINT: Adds option for minute bar writer to not write metadata
With the addition of the truncate function, there are cases where we'll
want to construct a BcolzMinuteBarWriter to call truncate, without
gathering all the metadata. This commit adds a write_metadata arg to its
init, which is True by default. If False is specified, no metadata is
written.

Requires adding logic to truncate to update end_session in metadata to
the truncate date.
2016-09-21 11:31:54 -04:00
Scott SandersonandGitHub 5e20a1bdd1 Merge pull request #1505 from quantopian/blaze-it
MAINT: Put us back on blaze master.
2016-09-21 11:18:27 -04:00
Eddie Hebert 9fd8ddda53 MAINT: Remove future_chain API method.
`future_chain` will be replaced by the as yet to be implemented method,
`data.current_chain`

Also removing `FutureChain` which will be replaced by another version
which only supports indexing and iteration.
2016-09-21 11:08:34 -04:00
Scott Sanderson 3477e26720 MAINT: Put us back on blaze master. 2016-09-21 10:46:57 -04:00
Eddie HebertandGitHub 21a3de8ce5 Merge pull request #1477 from quantopian/init-1.0.3-release-notes
DOC: Add skeleton for 1.0.3 release notes.
2016-09-21 10:36:31 -04:00
Eddie HebertandGitHub 9e0ef02ff6 Merge pull request #1494 from quantopian/remove-unused-update-dividends
MAINT: Remove unused method.
2016-09-21 10:36:12 -04:00
Scott SandersonandGitHub b584ccc187 Merge pull request #1504 from quantopian/pandas18-memory-stopgaps
PERF: Remove or defer calls to get_loc on large indices.
2016-09-21 10:18:57 -04:00
Scott Sanderson a9faf94945 PERF: Remove or defer calls to get_loc on large indices.
Mitigation for https://github.com/quantopian/zipline/issues/1503.
2016-09-21 06:18:31 -04:00
Scott SandersonandGitHub 9ea1af70a9 Merge pull request #1339 from quantopian/latest-numpy-pandas
Latest numpy and pandas
2016-09-20 22:03:49 -04:00
Scott Sanderson 9cc2ecf8d5 BUG: Remove set_trace and add test coverage. 2016-09-20 17:46:27 -04:00
Scott Sanderson c28ac1a4a5 MAINT: Bump blaze. 2016-09-20 17:12:09 -04:00
Scott Sanderson c5936b86d6 MAINT: Silence bad perf warning from pandas. 2016-09-20 17:12:09 -04:00
Scott Sanderson ab9a5d7060 MAINT: Use randint instead of random_integers. 2016-09-20 17:12:09 -04:00
Scott Sanderson 6e3bfe2d78 MAINT: Rebuild example data. 2016-09-20 17:12:09 -04:00
Scott Sanderson 2522ca28ae BUG: Don't fail on integral floats in event rules.
Coerce and warn instead.
2016-09-20 17:12:08 -04:00
Scott Sanderson 467a4f8225 MAINT: Bump blaze. 2016-09-20 17:12:08 -04:00
Scott Sanderson 5370948196 MAINT: Use sort_values instead of sort(). 2016-09-20 17:12:08 -04:00
Scott Sanderson ce76acce46 MAINT: Use df.resample().apply(). 2016-09-20 17:12:08 -04:00
Scott Sanderson ec89402a3e MAINT: Fix PerformanceWarning import. 2016-09-20 17:12:08 -04:00
Scott Sanderson 918de6ad26 MAINT: Use explicit floats in np.full. 2016-09-20 17:12:08 -04:00
Scott Sanderson f77892240a MAINT: Use specific versions in appveyor.yml. 2016-09-20 17:12:08 -04:00
Scott Sanderson ddef107fa1 BLD: Downgrade to scipy 0.17.
Anaconda doesn't have windows builds for scipy 0.18 (nor does
conda-forge.)
2016-09-20 17:12:08 -04:00
Scott Sanderson 46cf54b180 MAINT: Remove outdated compat code. 2016-09-20 17:12:07 -04:00
Scott Sanderson c6dc1db1f2 BLD: Update appveyor.yml for new pandas/numpy. 2016-09-20 17:12:07 -04:00
Scott Sanderson 6aeba11176 STY: Fix flake8 failures. 2016-09-20 17:12:07 -04:00
Scott Sanderson ebbd79c7db MAINT: Put scipy back in travis reqs. 2016-09-20 17:12:07 -04:00
Scott Sanderson 9e517691bb BLD: Remove old numpy/pandas versions from travis. 2016-09-20 17:12:07 -04:00
Scott Sanderson 48a44f321a DOC: Note where cleanup happens. 2016-09-20 17:12:07 -04:00
Scott Sanderson 4ba064dae7 MAINT: Don't make datetime64 from tz-aware Timestamp.
It's slow and deprecated.
2016-09-20 17:12:07 -04:00
Scott Sanderson f24db9c30c DOC: Typo in comment. 2016-09-20 17:12:07 -04:00
Scott Sanderson b639555404 MAINT: Use errors='coerce'.
coerce=True is deprecated.
2016-09-20 17:12:07 -04:00
Scott Sanderson 493e18252d MAINT: Temporarily ignore pandas warnings in categoricals.
Pandas 0.18 doesn't like having null-ish values in categoricals.  Fixing
this properly requires re-thinking the semantics for missing_value on
pipeline terms, so we're punting on that until after we've upgraded to
0.18.
2016-09-20 17:12:07 -04:00
Scott Sanderson a9c02935c6 Revert "MAINT: Remove support for custom string Column missing values."
This reverts commit 1b1e842e2339d6d0ee40cdfe34dcd27b4e4a7c0c.
2016-09-20 17:12:07 -04:00
Scott Sanderson ed365dc5fe MAINT: Remove support for custom string Column missing values.
Pandas 0.18 deprecated passing "null-ish" values to pd.categorical.  The
expectation, instead, is that you use categorical's native support for
missing data, which means the user will always get NaN's for missing
entries of the categorical.

A follow-up to this change should probably drop support for custom
missing values entirely and to use LabelArray/categorical for integer
data.
2016-09-20 17:12:07 -04:00
Scott Sanderson da8ed8919e MAINT: Pandas compat for rolling_*. 2016-09-20 17:12:07 -04:00
Scott Sanderson 52166e9958 MAINT: Pass float to np.full explicitly. 2016-09-20 17:12:07 -04:00
Scott Sanderson 4c3c2fd13c MAINT: Don't use convert_objects().
It's not necessary, and it's deprecated.
2016-09-20 17:12:07 -04:00
Scott Sanderson a1273cd669 MAINT: Fix warnings from numpy labelarray methods. 2016-09-20 17:12:07 -04:00
Scott Sanderson af5f4be17c MAINT: Fix warnings from numpy on NaT comparison. 2016-09-20 17:12:07 -04:00
Scott Sanderson 9bd6cab115 MAINT: Pass float explicitly. 2016-09-20 17:12:07 -04:00
Scott Sanderson b9c2e8c1c6 MAINT: Use sort_values instead of sort().
Sort is deprecated.
2016-09-20 17:12:07 -04:00
Scott Sanderson 9aa866e434 MAINT: Use sort_values() instead of sort().
pd.DataFrame.sort() is deprecated.
2016-09-20 17:12:07 -04:00
Scott Sanderson f30fc28b5c MAINT: Pass float explicitly to numpy. 2016-09-20 17:12:07 -04:00
Scott Sanderson ef88dfdad2 MAINT: Use dataframe.iteritems instead of iterkv.
iterkv is deprecated.
2016-09-20 17:12:07 -04:00
Scott Sanderson 74277490d5 BUG: Use arrays for week/month group calculations.
In pandas 0.18, the behavior of ``nth()`` changed so that Grouper no
longer can be easily used to recover group labels.

Instead of using the built-in grouper behavior, we use a groupby on two
arrays we build ourselves.  This recovers the original behavior, and is
about 2x faster as a bonus.
2016-09-20 17:12:07 -04:00
Scott Sanderson f8734e8721 MAINT/TEST: Clarify test_events.
- Refer to ``sessions`` instead of periods.
- Use ``toolz.concat`` instead of an O(N ** 2) sequence of appends.
2016-09-20 17:12:07 -04:00
Scott Sanderson 259f10a2d9 MAINT: Pass float to np.full explicitly. 2016-09-20 17:12:07 -04:00
Scott Sanderson 434d7c69d3 TEST/MAINT: Silence no_checkpoints warning. 2016-09-20 17:12:07 -04:00
Scott Sanderson 905df55a2d MAINT: Use float in np.full. 2016-09-20 17:12:07 -04:00
Scott Sanderson c4e114c28f MAINT: Pass explicit dtype to np.full. 2016-09-20 17:12:07 -04:00
Scott Sanderson dafe49fcca MAINT: Fix failures/warnings in test_api_shim.py
- Fixes a warning on indexing with a float that ultimately came from
  pd.Timedelta.total_seconds().  Adds ``timedelta_to_integral_seconds``
  and ``timedelta_to_integral_minutes()`` functions and replaces various
  usages of ``int(delta.total_seconds())`` with them.

- Fixes a warnings triggered in ``_create_daily_stats`` from
  passing tz-aware datetimes to np.datetime64.
2016-09-20 17:12:07 -04:00
Scott Sanderson e43a3e8b1b MAINT: Use arange instead of rolling_count.
It's faster, and rolling_count is deprecated.
2016-09-20 16:24:55 -04:00
Scott Sanderson e33c42b3a9 MAINT: Update fetcher for pandas 0.18.
- Remove support for usecols=[].
- Use sort_values instead of sort().
- Use errors='coerce' instead of coerce=True.
2016-09-20 16:24:55 -04:00
Scott Sanderson 61a56492e6 ENH: Make INT_DTYPES_BY_SIZE_BYTES ordered. 2016-09-20 16:24:55 -04:00
Scott Sanderson fc3eac36aa DOC: Update LabelArray docstring. 2016-09-20 16:24:55 -04:00
Scott Sanderson b06ef66f44 DOC: Remove out of date comment. 2016-09-20 16:24:55 -04:00
Scott Sanderson 0d8e99956e MAINT: Fix numpy deprecation warnings. 2016-09-20 16:24:55 -04:00
Scott Sanderson be30c0072d MAINT: Explicitly use float64 in test. 2016-09-20 16:24:54 -04:00
Scott Sanderson d2f0632101 MAINT: Don't use .loc with integers. 2016-09-20 16:24:54 -04:00
Scott Sanderson 29d5854aa1 MAINT: Bump numpy and pandas. 2016-09-20 16:24:54 -04:00
Richard FrankandGitHub 80227eda57 Merge pull request #1493 from quantopian/enumpycal
Enumpycal
2016-09-19 16:27:13 -04:00
Richard Frank ef04fe3a9b PERF: Use empyrical with ndarrays instead of Series 2016-09-19 15:51:06 -04:00
Richard Frank 73a61caaeb MAINT: Removing unused array and unused attribute 2016-09-19 15:19:30 -04:00
Jean BredecheandGitHub 657e5f92e7 Merge pull request #1497 from quantopian/you-count-way-too-slowly
PERF: Be smarter about counting the number of minutes across a contiguous bunch of sessions.
2016-09-19 14:34:11 -04:00
Jean Bredeche 8048cdcfb0 PERF: Be smarter about counting the number of minutes across a contiguous bunch of sessions. 2016-09-19 13:25:03 -04:00
Andrew DanielsandGitHub 4a2faa3e13 ENH: Adds truncate method to BcolzMinuteBarWriter (#1499) 2016-09-19 13:02:48 -04:00
Eddie HebertandGitHub 72a8316ca7 Merge pull request #1496 from quantopian/revert-load-adjustments
Revert "Merge pull request #1490 from quantopian/use-load-adjustments…
2016-09-19 09:38:02 -04:00
Eddie Hebert 6486e64530 Revert "Merge pull request #1490 from quantopian/use-load-adjustments-for-history"
This reverts commit 86c7635b45, reversing
changes made to c77f2b92df.

Some real world cases hit errors with this change, due to the new offset
logic attempting to create Adjustments with invalid parameters.

Will identify exact conditions that cause this error and add as a test
case before remerging.
2016-09-19 08:53:31 -04:00
Eddie Hebert 7b74257f28 MAINT: Remove unused method.
Dividends are read from AdjustmentReader.
2016-09-16 16:50:10 -04:00
Jean BredecheandGitHub e21fa37e22 Merge pull request #1492 from quantopian/cache-minute-to-session-lookups
PERF: Save up to 80% of the calls to minute_to_session_label
2016-09-16 16:07:13 -04:00
Jean Bredeche 31cbdde7f0 PERF: Save up to 75% of the calls to minute_to_session_label
One year NYSE test that buys a lot triggers 492,963 calls to
minute_to_session_label.  Only 98924 ~(390 * 252) make it past the
cache and trigger the heavier computation.
2016-09-16 15:18:50 -04:00
Jean BredecheandGitHub 0cf276d14a Merge pull request #1491 from quantopian/faster-lru-cache-take-2
ENH: Switching from cachetools.LRUCache to lru-dict's LRU cache.
2016-09-16 11:29:45 -04:00
Jean Bredeche a7f345e651 ENH: Switching from cachetools.LRUCache to lru-dict's LRU cache.
lru-dict is written in C and seems much more performant.
2016-09-16 11:03:13 -04:00
Eddie HebertandGitHub f2a1263d90 Merge pull request #1490 from quantopian/use-load-adjustments-for-history
MAiNT: Use load_adjustments for history.
2016-09-15 16:01:23 -04:00
Jean BredecheandGitHub ed08f25224 Merge pull request #1488 from quantopian/who-said-you-could-forward-fill-stop-that
ENH: Make reader.get_value raise NoDataOnDate if the date is not in the calendar.
2016-09-15 15:41:36 -04:00
Eddie Hebert 1d06a779b3 MAiNT: Use load_adjustments for history.
Instead of `HistoryLoader` containing separate adjustment calculation
logic, use `SQLiteAdjustmentReader.load_adjustments`.

This change required the addition of two offset parameters to
`load_adjustments` since the perspective on the data from within
`schedule_function` is skewed from how Pipeline looks at historical
data.

This is working towards creating an `AdjustmentReader` abc which
`SQLiteAdjustmentReader` and a upcoming continuous future adjustment
reader will share.
2016-09-15 15:32:10 -04:00
Jean Bredeche 0fd35e7fd1 ENH: Make reader.get_value raise NoDataOnDate if the date is not in the calendar.
DataPortal now catches the NoDataOnDate exception and returns nan for
OHLC and 0 for V.

Price is still forward filled, unchanged.
2016-09-14 22:21:43 -04:00
Richard Frank 644a33e11b BLD: empyrical doesn't have a binary dependency on numpy
so we don't need to tag its conda packages with the numpy version
2016-09-14 21:04:07 -04:00
Scott SandersonandGitHub 7ac024fb5c Merge pull request #1484 from quantopian/refcount-pipelines
PERF: Release unneeded pipeline terms.
2016-09-14 20:24:10 -04:00
Scott Sanderson 7c58bf1e5b STY: Flake8 and parameter rename. 2016-09-14 14:45:00 -04:00
Jean BredecheandGitHub cfd08f8d6b Merge pull request #1486 from quantopian/all-the-readers-unite
MAINT: Add BarReader base class for both minute and session readers
2016-09-14 14:32:01 -04:00
Jean Bredeche 2856fd0ecf MAINT: Add BarReader base class for both minute and session readers 2016-09-14 13:47:12 -04:00
Scott Sanderson a0e1b881aa MAINT: Move refcount management into TermGraph. 2016-09-14 11:16:40 -04:00
Scott Sanderson 6aa885dbeb PERF: Release unneeded pipeline terms.
Refcount pipeline terms during execution and release terms once they're
no longer needed.

This dramatically reduces memory usage on large pipelines.
2016-09-13 23:28:25 -04:00
John RicklefsandGitHub 1f859d34e5 MAINT: Add additional fields to __getitem__ for Order (#1483)
These were previously available like the others.
2016-09-13 15:49:16 -04:00
John RicklefsandGitHub e6a647edf1 Revert "added DGZ to delete list" (#1481)
This reverts commit a5ecaf4c3a.

This causes downstream problems; unsure why, Jamie advised
reverting.
2016-09-13 14:45:12 -04:00
Richard FrankandGitHub b729ddd54f Merge pull request #1479 from quantopian/run_algo-defaults
BUG: run_algorithm with no data source should default
2016-09-12 13:00:33 -04:00
Richard Frank 6afdb318ee BUG: run_algorithm with no data source should default
to 'quantopian-quandl' bundle
2016-09-12 12:17:17 -04:00
Richard FrankandGitHub 7a10d9392d Merge pull request #1467 from quantopian/check_param-string_types
Check param string types
2016-09-08 14:59:38 -04:00
Kathryn GlowinskiandGitHub 9ad670bd46 More Fuzzy Symbol Fixes (#1475)
* REF: More options before raise MultiFound.

* TST: Checks corner case for fuzzy matching.
2016-09-08 14:52:57 -04:00
Eddie Hebert 3a82049a00 DOC: Add skeleton for 1.0.3 release notes.
Post 1.0.2 cleanup.
2016-09-08 14:22:01 -04:00
Scott SandersonandGitHub c66d3ad820 Merge pull request #1471 from quantopian/fix-slow-startup
PERF: Remove import-time calendar creations.
2016-09-08 10:21:00 -04:00
Scott Sanderson ff1bc51bd1 STY: Fix flake8. 2016-09-07 21:58:15 -04:00
Scott Sanderson 85ce093270 MAINT: Updates from Joe's PR feedback. 2016-09-07 20:42:19 -04:00
James McCorristonandGitHub bb22af747d Merge pull request #1434 from quantopian/update-leveraged-etfs
MAINT: Update leveraged ETF list
2016-09-07 13:48:12 -04:00
Jamie McCorriston e6ef82fc4c added DGZ to delete list 2016-09-07 13:12:34 -04:00
Eddie HebertandGitHub 6c7af70155 Merge pull request #1473 from quantopian/release-1.0.2
REL: Prepare for 1.0.2 release.
2016-09-06 21:33:49 -04:00
Eddie Hebert b1e50b3434 REL: Prepare for 1.0.2 release.
Update release notes.

Generate api stubs.
2016-09-06 16:59:34 -04:00
Joe JevnikandGitHub 07cdd291a1 Merge pull request #1472 from quantopian/branch-protect-hook-stopped-me-from-pushing-this-commit-directly-;_;
ENH: improve warning for protocol getitem
2016-09-06 15:42:14 -04:00
Joe Jevnik 863e2ffbea ENH: improve warning for protocol getitem 2016-09-06 15:11:43 -04:00
Scott Sanderson bd420f938b MAINT/TEST: Update default calendar smoketest. 2016-09-06 14:13:32 -04:00
Joe JevnikandGitHub 1e030c77b2 Merge pull request #1449 from quantopian/getitem-is-not-getattr
MAINT: remove __getitem__ as alias of __getattr__
2016-09-06 13:48:17 -04:00
Joe Jevnik b66d9ae976 DEV: update copyright in protocol.py (added code) 2016-09-06 12:42:06 -04:00
Joe Jevnik 631984e1f5 ENH: just deprecate __getitem__, don't remove 2016-09-06 12:39:29 -04:00
Kathryn GlowinskiandGitHub 6a3db75a92 Merge pull request #1462 from quantopian/symbol-lookup-raises
Symbol lookup raises
2016-09-06 11:02:07 -04:00
kglowinski e7e4db0701 BUG: Fixing 2/3 compat. 2016-09-06 10:12:01 -04:00
kglowinski 15ab8ac95e BUG: Handle case with mult symbol options for same sid. 2016-09-06 10:12:01 -04:00
kglowinski 8056dd8a90 BUG: Fixing SymbolNotFound to be raised. 2016-09-06 10:12:00 -04:00
Scott Sanderson a8a2cc1582 PERF: Remove module-scope calendar creations.
Remove module scope invocations of `get_calendar('NYSE')`, which cuts
zipline import time in half on my machine. This make the zipline CLI
noticeably more responsive, and it reduces memory consumed at import
time from 130MB to 90MB.

Before:

$ time python -c 'import zipline'

real    0m1.262s
user    0m1.128s
sys     0m0.120s

After:

$ time python -c 'import zipline'

real    0m0.676s
user    0m0.536s
sys     0m0.132s
2016-09-06 09:57:23 -04:00
John RicklefsandGitHub 43b9fa84d7 Revert "BUG: Capital change deltas rely on cash, not portfolio_value" (#1470)
This reverts commit 5b1aa5ec55.

The paradigm is: we're calculating a new capital base for the
performance period. We are therefore using the total
portfolio_value, not just the cash, to calculate the
difference from the specified target as the algorithm
has meaningful holdings.
2016-09-05 14:12:04 -04:00
Richard Frank 7f6db68fc6 BUG: Fix up check_parameters usage of string_types
and corresponding tests
2016-09-02 16:47:32 -04:00
phil.zhangandRichard Frank eb6b6d046d BUG: Change str to string_types to avoid errors
When in python2.7, and unicode_literals is imported
type check will raise error because 'type' is not str but unicode
2016-09-02 16:47:13 -04:00
Scott SandersonandGitHub 548e0675be Merge pull request #1466 from quantopian/disallow-length-1-regressions
ENH: Dont allow length=1 regressions/correlations.
2016-09-02 15:49:03 -04:00
Eddie HebertandGitHub ddcba8733d Merge pull request #1464 from quantopian/add-coverage-for-last-traded-dt
TST: Add direct coverage for get last traded dt
2016-09-02 14:59:21 -04:00
Scott SandersonandGitHub b946c657b7 Merge pull request #1420 from quantopian/add-cython-cleanup
MAINT: Add script to clean out compiled files.
2016-09-02 14:16:18 -04:00
Scott Sanderson b0a93d57a0 DOC: Clarify expect_bounded docstring. 2016-09-02 13:33:55 -04:00
Eddie Hebert 948d813b84 TST: Add direct coverage for get last traded dt
Check that both an equity and future can return expected values for
`get_last_traded_dt`.
2016-09-02 13:19:46 -04:00
Eddie HebertandGitHub d7eb845c7f Merge pull request #1465 from quantopian/remove-unused-adjustments-in-data-portal
MAINT: Remove unused data portal methods.
2016-09-02 13:15:12 -04:00
Scott SandersonandGitHub 28bca7cbd7 DEV: Find .c and .so files with regex. 2016-09-02 12:56:36 -04:00
Scott Sanderson 12101c55c8 STY: Don't assign variables that won't be created. 2016-09-02 12:53:01 -04:00
Scott Sanderson 8b2446aec6 ENH: Dont allow length=1 regressions/correlations.
They're not meaningful, and they cause warnings from numpy.

Implemented in terms of a new preprocessor, `expect_bounded`, which
takes a tuple of `upper_bound` and `lower_bound`.
2016-09-02 12:49:09 -04:00
Eddie Hebert 1269250dde MAINT: Remove unused data portal methods.
The apply adjustments behavior had been moved to the `HistoryLoader`
class.
2016-09-02 12:12:22 -04:00
Ana RuelasandGitHub 8f3e0cbfb2 Merge pull request #1463 from quantopian/rm-risk-adjustments
BUG: Do not adjust returns for sharpe and sortino
2016-09-02 11:32:02 -04:00
Ana Ruelas ec7e4f2333 BUG: Do not adjust returns for sharpe and sortino 2016-09-02 10:41:50 -04:00
Eddie HebertandGitHub c5c7a4ac4a Merge pull request #1460 from quantopian/daily-aggregator-corner-cases
TST/BUG: Full coverage on resample module.
2016-09-01 17:24:56 -04:00
John RicklefsandGitHub 8595ca81cb Merge pull request #1459 from quantopian/target_cash_capital_change_from_raw_cash
BUG/ENH: Fix behavior of 'target' capital changes
2016-09-01 16:54:56 -04:00
Eddie Hebert baff6a84bc TST/BUG: Full coverage on resample module.
test_resample now fully covers the resample module.

Fix a bug exposed by increased coverage, where daily aggregation on
`high` would return `nan` for an asset instead of 1) during the
course of day `1d` history was called on non-consecutive minutes and 2)
either, a) the value for the previously inspected dt was `nan` or b)
there were only `nan`s between the previous and current dt.

`low` had a similar bug which was only triggered if the value for the
previously inspected dt was `nan`.
2016-09-01 16:41:45 -04:00
John Ricklefs 0d40b84550 ENH: Allow passing additional adjustments to calculate_capital_changes
If subclasses have additional capital change information that
is required to correctly calculate the target values for
cash capital changes, it can now be provided via
"portfolio_value_adjustment".
2016-09-01 16:04:46 -04:00
John Ricklefs 3ab907ee4f BUG: Capital change deltas rely on cash, not portfolio_value
The value of holdings is irrelevant when altering the
capital base of the current perf period.
2016-09-01 15:19:55 -04:00
Eddie HebertandGitHub e2300c73bf Merge pull request #1458 from quantopian/cover-all-public-methods-on-resample
TST/BUG: Cover all reindex session public methods.
2016-09-01 14:20:19 -04:00
Eddie Hebert 59d06a1883 TST/BUG: Cover all reindex session public methods.
Increase coverage on `ReindexSessionBarReader` so that all methods which
are considered part of the interface are covered by `test_resample`.

Fix bug in `get_value`, exposed by increased coverage, where the
`NoDataOnDate` exception was bubbling from the bcolz reader all the way
up when a session which was a holidy on the underlying reader was passed
to the reindex reader. (The reindex reader should return nan/0 in that
case.)

Also, move location of data index exceptions so that they are agnostic
to bcolz/us_equity_pricing; since the exception is now used by the
resample module to fix aforementioned bug.
2016-09-01 11:51:00 -04:00
Jean BredecheandGitHub 95329180bd Merge pull request #1408 from quantopian/really-can-i-trade-how-about-now
ENH: Update can_trade to check exchange time
2016-08-31 22:04:06 -04:00
Jean Bredeche 46c0c064fe ENH: Update can_trade to check exchange time
BarData now takes the trading calendar as a parameter.

can_trade now checks if the asset’s exchange is open at the current or
next market minute (defined by the given trading calendar).
2016-08-31 21:22:06 -04:00
Eddie HebertandGitHub af75a1f67c Merge pull request #1457 from quantopian/allow-last-date-for-session-get-last-traded-dt
TST: Fix get_last_traded_dt on bcolz daily reader.
2016-08-31 15:53:36 -04:00
Jean BredecheandGitHub af20cdbe9d Merge pull request #1456 from quantopian/future-chain-cleanup
ENH: Simplified implementation of FutureChain object (not user-facing API)
2016-08-31 15:36:57 -04:00
Eddie Hebert 1bebad5b68 TST: Fix get_last_traded_dt on bcolz daily reader.
Remove special handling for the last session of an asset, which was
moving the last traded back a session.

If the asset has data on a session, `get_last_traded_dt` should always
return that session if it is the parameter to the method.
2016-08-31 14:59:58 -04:00
Jean Bredeche d1160439d2 ENH: Simplified implementation of FutureChain object (not user-facing API).
No longer auto-updates its internal as-of date, instead requires an explicit
as-of date from the consumer.

Take a static list of contracts (instead of needing an assetfinder).

Instead of the as_of method, the user-facing API now lets you pass in an
offset, which is defined as an integral number of sessions.
2016-08-31 14:44:02 -04:00
Joe Jevnik fcde54297c MAINT: remove __getitem__ as alias of __getattr__ 2016-08-31 12:38:20 -04:00
Jean BredecheandGitHub f5d6bfca4d Merge pull request #1455 from quantopian/cache-future-chain-lookups
ENH: Put a cache in front of future chain lookups
2016-08-31 11:26:14 -04:00
Jean Bredeche 8d61e16df9 ENH: Put a cache in front of future chain lookups
Cache the last 100 rootsymbol/session pairs, since future chains never
change inside a session.
2016-08-31 10:40:11 -04:00
Eddie HebertandGitHub 8863d007ce Merge pull request #1452 from quantopian/begin-cover-reindex-resample
TST: Increase coverage for  reindex reader methods
2016-08-31 10:31:14 -04:00
Ana RuelasandGitHub 22de78fdb5 Merge pull request #1450 from quantopian/empyrical-v-update
Empyrical v update
2016-08-30 20:29:28 -04:00
Jean BredecheandGitHub a813f245e2 Merge pull request #1451 from quantopian/zero-means-zero
ENH: Avoid unnecessary work with missing data.
2016-08-30 20:07:25 -04:00
Jean Bredeche a37141fb98 ENH: Avoid unnecessary work with missing data. 2016-08-30 17:16:08 -04:00
Eddie Hebert 544dda115c TST: Increase coverage for reindex reader methods
Add direct coverage on last_available_dt.

Also move reader creation into the instance fixture.

This patch attempted to add coverage on `get_last_traded_dt`, but in doing
so, revealed a bug in `BcolzDailyBarReader.get_last_traded_dt` when
requesting the last trading session of an asset.
When that is fixed, the skip can be removed.
2016-08-30 16:43:58 -04:00
Ana Ruelas 3698362030 BLD: Update to empyrical 0.1.11 2016-08-30 16:41:57 -04:00
Jean BredecheandGitHub e574b7b042 Merge pull request #1442 from quantopian/schedule-all-the-hours
ENH: Let event offsets be up to 12 hours.
2016-08-30 16:34:23 -04:00
Eddie HebertandGitHub 624b4659f1 Merge pull request #1446 from quantopian/use-us-futures-in-test-resample
TST: Use futures cal in resample suite.
2016-08-30 10:24:18 -04:00
Richard Frank 9919d47898 BLD: Tag empyrical conda packages with numpy version 2016-08-29 17:12:05 -04:00
John RicklefsandGitHub 674a6200b4 Merge pull request #1437 from quantopian/empyrical_perf
PERF: Reduce calculations performed by empyrical
2016-08-29 16:20:41 -04:00
Eddie Hebert bce159f275 TST: Use futures cal in resample suite.
Instead of CME, use the futures cal, which should now be the standard
calendar throughout; though some tests remain to be ported.
2016-08-29 15:43:39 -04:00
Eddie HebertandGitHub 5b333df10e Merge pull request #1445 from quantopian/cover-resample-first-trading-day
TST: Cover resample bar first_trading_day method.
2016-08-29 15:38:07 -04:00
Ana Ruelas c984cdb247 TST: Rebuild example data due to changes in beta calculation 2016-08-29 15:11:37 -04:00
Andrew DanielsandGitHub 60c485c1ed ENH: Adds table_len method to BcolzMinuteBarReader (#1436)
To get the length of the underlying table for a given sid.
2016-08-29 15:07:08 -04:00
Eddie Hebert 7146edbe7d TST: Cover resample bar first_trading_day method.
Add a test to directly cover the first_trading_day method via the
`test_resample` suite. (The lack of coverage was exposed when testing
against real data.)

Also, refactor resample bar tests so that session bar reader is set up
in instance fixture.
2016-08-29 15:00:08 -04:00
Eddie HebertandGitHub 50e175bad2 Merge pull request #1444 from quantopian/use-session-label-on-daily
BUG: Use session label instead of date for 1d.
2016-08-29 14:05:39 -04:00
Eddie Hebert 5dfd2286b3 BUG: Use session label instead of date for 1d.
`1d` history calls were failing on key errors when using the
`us_futures` calendar, because of timestamps occuring before a midnight
would present the wrong midnight (i.e. the midnight before the session,
instead of the following midnight, which is the label for the current
session.)

Tests will follow when bringing up coverage on resample and data portal
modules.
2016-08-29 13:25:14 -04:00
Ana Ruelas 74ee33fd58 MAINT: Update conda recipe for empyrical 2016-08-29 13:07:25 -04:00
John Ricklefs e22edbebae PERF: Send pre-adjusted returns to information_ratio 2016-08-29 12:13:19 -04:00
John Ricklefs c713d4798f PERF: Risk-adjust returns series once before calling empyrical
This prevents empyrical from having to subtract
the risk-free rate from the returns in each
individual method.
2016-08-29 12:13:19 -04:00
John Ricklefs 201e72aee1 PERF: Pass known calculations into empyrical methods
For example, to prevent `alpha` from internally calling
`beta` a second time, pass the previously-calculated
`beta` value in.

Requires empyrical 0.1.10 from pypi
2016-08-29 12:13:19 -04:00
Jean Bredeche e0cdc7bc3a ENH: Let event offsets be up to 12 hours. 2016-08-29 09:33:40 -04:00
Jean BredecheandGitHub 339417d27f Merge pull request #1441 from quantopian/cherry-pick-futures--stuff
ENH: Merging a few futures-related changes
2016-08-28 22:00:31 -04:00
Jean Bredeche 51da755c43 TST: Some futures-related fixtures cleanup. 2016-08-28 21:33:54 -04:00
Jean Bredeche 0cc08d79b4 ENH: Add new parameter to schedule_function that accepts a trading
calendar.
2016-08-28 21:33:42 -04:00
Eddie HebertandGitHub 3b502f53e4 Merge pull request #1435 from quantopian/use-dispatch-reader-in-data-portal
ENH: Add asset dispatch to data portal.
2016-08-26 14:18:09 -04:00
Eddie Hebert a4131ea84b ENH: Add asset dispatch to data portal.
Combine the equity and future readers into asset dispatch readers, so
that simulations that use both asset types can access data for each.

This patch enables `history` for future assets in algorithms; however,
it does not add extra coverage in the `test_data_portal` or `test_history`
to cover future assets. Those tests will follow, however putting this in
separately since it shows that the wrapping of the readers in the asset
dispatch reader does not break existing equity strategies.
2016-08-26 13:29:08 -04:00
LotannaEzenwa 26797b132c create add/delete lists 2016-08-26 11:52:05 -04:00
Eddie HebertandGitHub bf49a6541f Merge pull request #1433 from quantopian/dispatch-bar-reader
MAINT: Add a reader which dispatches on asset type
2016-08-26 08:44:20 -04:00
Eddie Hebert 413ea3d9d5 MAINT: Add a reader which dispatches on asset type
Add `AssetDispatchSessionBarReader` and corresponding minute and session
bar version of that reader.
This reader routes requests to the appropriate reader based on the asset
type of the requested sids.

`load_raw_array` in the dispatch reader batches the sid by asset type
and then interleaves the results in the out arrays, so that the arrays
data corresponds with sids in the order that sids are passed to the
method, to meet the expected behavior of `load_raw_arrays`.

The dispatch redaer is intended for use by the data portal when using
both future and equities. The dispatch reader will also be passed to the
to the `HistoryLoader`s contained within the data portal, where the
batched `load_raw_arrays` will be used.

Also, BUG:
- Fix the return of `MinuteResampleSessionBarReader.load_raw_arrays` to
match all other readers.
- Use the input dt for the `MinuteResampleSessionBarReader.load_raw_arrays`
as a session label, instead of a minute dt, since it is a session bar
reader.
(Both of these bugs where discovered when using the resample reader for
future data in the dispatch tests.)
2016-08-25 16:29:45 -04:00
Eddie HebertandGitHub 0dd01650f1 Merge pull request #1432 from quantopian/reindex-reader
ENH: Add a reader base which reindexes results.
2016-08-25 09:34:06 -04:00
Richard FrankandGitHub 0b9084edec Merge pull request #1430 from quantopian/ingest-versions
Ingest versions
2016-08-24 16:49:42 -04:00
Eddie Hebert fc8cf38a6e ENH: Add a reader base which reindexes results.
Working towards history results which contain mixed asset types, add
a reader which makes `load_raw_arrays` return results indexed on the
session/minute ranges specified by the specified `trading_calendar`
instead of the calendar of the backing reader.

This reader will be used to make Equity readers align with Future
readers. It is intended for use as part of another reader (which will
dispatch queries based on asset type and then recombined results) which
will be passed to the `[Minute|Session]HistoryLoaders in the data portal.
2016-08-24 16:28:19 -04:00
Richard Frank abdfe0265d BLD: alembic is now a production requirement 2016-08-24 15:32:31 -04:00
Richard Frank cf6ec9fd73 BUG: More python3 compat 2016-08-24 15:32:31 -04:00
Richard Frank 419bd1e3b5 DEV: zipline ingest can downgrade the assets db
This lets us publish an "old" db version for the most recent release
of zipline, using the latest code base.
2016-08-24 15:32:30 -04:00
Richard Frank 418e8901f4 MAINT: Put downgrade in transaction 2016-08-24 13:24:07 -04:00
Richard Frank bc87ea4efb MAINT: Consolidate coercion to sqlite conn/eng 2016-08-24 13:24:07 -04:00
Richard Frank 6d473ce23f MAINT: Clean up usage of engine versus connection 2016-08-24 13:24:07 -04:00
Eddie HebertandGitHub 7ac0978f0c Merge pull request #1431 from quantopian/spot-price-get-value
MAINT: Standardize reader get value methods.
2016-08-24 13:22:13 -04:00
Andrew DanielsandGitHub acb2cf118e MAINT: Modifies minute bars to use a dict of OHLC ratios (#1428)
For scaling up pricing data before writing to bcolz, the writer now
accepts a dict mapping each sid to the ratio to use. It still accepts a
single ratio as default_ohlc_ratio, which is used as a fallback if no
mapping exists for a given sid. The default is OHLC_RATIO (1000).

This allows better handling of futures pricing data, where the required
precision across root symbols is not consistent.
2016-08-24 13:14:16 -04:00
Eddie Hebert a3c1f4ce36 MAINT: Standardize reader get value methods.
The daily/session bar reader's `spot_price` took the same parameters and
returned the same kind of output as the minute bar reader's `get_value`.

Standardize on one method to make a common interface, which may be
formally factored out in a later patch; to help enable writing reader
implementations or mixins which can be agnostic to the bar frequency.
2016-08-24 12:46:36 -04:00
Ana RuelasandGitHub 20f9241252 Merge pull request #1322 from quantopian/move_risk_calculations
Move risk calculations
2016-08-23 18:39:22 -04:00
Ana Ruelas 1f829f8c92 MAINT: Update whatsnew for empyrical changes 2016-08-23 17:02:12 -04:00
Ana Ruelas a4638026c7 TST: Rebuilt example data using empyrical 2016-08-23 13:49:48 -04:00
Ana Ruelas f0af856c13 TST: Update to empyrical, increase test coverage
ENH: Resolve rebase conflict by using updated example_data.tar

TST: Increase test coverage for risk portion of zipline
2016-08-23 13:49:43 -04:00
Ana Ruelas 902865cf71 ENH: Use qrisk to calculate risk metrics in cumulative and period
TST: Remove metric correctness testing from period and cumulative tests

ENH: Removed answer key and related files

ENH: Update qrisk version
2016-08-23 13:49:27 -04:00
Eddie HebertandGitHub 78015066c8 Merge pull request #1427 from quantopian/use-equities-calendar-in-equity-fixtures
TST: Use equity calendar when writing equity data
2016-08-23 12:15:00 -04:00
Eddie Hebert 6b2d614227 TST: Use equity calendar when writing equity data
Use the equity calendar to write equity data, even when the simulation
calendar has been set to a different calendar.

Discovered when writing a test that used a calendar for future asset
data, but also wrote equity data.
2016-08-23 11:11:32 -04:00
Richard FrankandGitHub 0c12e4a5a6 Merge pull request #1426 from quantopian/really-ingest
BUG: Fixes zipline ingest with non-default bundle on python 2
2016-08-22 18:56:27 -04:00
Richard Frank f247bc8d05 BUG: Fixes zipline ingest with non-default bundle on python 2 2016-08-22 18:30:39 -04:00
Andrew DanielsandGitHub 193b657bfe BUG: Fixes BcolzMinuteBarMetadata to read the version correctly (#1425)
We were mistakenly using the minute_per_day field.

We now expose from the metadata object the version from which the
metadata was read. This allows a new test that verifies the version is
read correctly.
2016-08-22 17:45:07 -04:00
Scott SandersonandGitHub 5be7e006e4 Merge pull request #1423 from quantopian/fix-sharedoc
Fix sharedoc
2016-08-22 14:51:05 -04:00
Lotanna EzenwaandGitHub 6fc5d7360d Merge pull request #1422 from quantopian/fix-ewma-constructors
BUG: Add kwargs to ewma constructors
2016-08-22 14:29:10 -04:00
Richard FrankandGitHub 8af09141f9 Merge pull request #1424 from quantopian/no-more-symbols
DOC: Updated more docs to remove --symbols, which was removed
2016-08-22 13:43:56 -04:00
Richard Frank 4c2783f7ca DOC: Updated more docs to remove --symbols, which was removed 2016-08-22 13:29:16 -04:00
Scott Sanderson ae121ec1dc MAINT: Simpler impl of pad_lines_after_first. 2016-08-22 13:14:31 -04:00
LotannaEzenwa c19d2855ad Added kwargs to ewma constructors
fixed typos
2016-08-22 13:14:23 -04:00
Scott Sanderson d52ff04626 DOC: Fix docs formatting for sharedoc.
The first line of indentation was incorrect.
2016-08-22 13:01:32 -04:00
Jean BredecheandGitHub 2b5ae892f8 Merge pull request #1407 from quantopian/minute_panel_daily_history
ENH: Add fast "vectorized" `minute_to_session_label` for DatetimeIndex
2016-08-22 10:27:40 -04:00
Scott Sanderson a3df81395a MAINT: Add script to clean out compiled files. 2016-08-22 08:53:06 -04:00
Richard FrankandGitHub 2eff193759 Merge pull request #1418 from quantopian/all-calendars
All calendars
2016-08-22 08:48:33 -04:00
Richard Frank cb097a2b80 DOC: Added licenses to calendar modules 2016-08-21 17:19:59 -04:00
Richard Frank 19c9bc2f41 MAINT: Removed unused holiday definitions 2016-08-21 17:19:59 -04:00
Richard Frank 09bd2abe2f BUG: Fix and test getting all default calendars 2016-08-21 17:19:59 -04:00
John RicklefsandGitHub aaa678d338 Merge pull request #1416 from quantopian/exch_full_synthetic
ENH: Expose exchange_full on all Asset types
2016-08-20 13:51:29 -04:00
John Ricklefs 8e3cc484db ENH: If no exchange_full provided, use exchange 2016-08-19 16:45:52 -04:00
John Ricklefs ccde5cbf56 ENH: Add exchange_full to all Assets, incl. Futures. 2016-08-19 16:45:52 -04:00
John Ricklefs fce87015d2 ENH: Expose exchange_full on Equity objects 2016-08-19 15:59:52 -04:00
Andrew DanielsandGitHub 5fb415eb12 ENH: Adds QuantopianUSFuturesCalendar (#1414)
For trading US futures across the exchanges supported by Zipline.
2016-08-19 13:40:09 -04:00
Eddie HebertandGitHub 653865b34c Merge pull request #1413 from quantopian/normalize-equity-future-in-data-portal
MAINT: Remove future/equity distinction.
2016-08-18 23:50:36 -04:00
Richard FrankandGitHub 2030dd02a1 Merge pull request #1409 from quantopian/doc-zipline-run
DOC: Replace run_algo.py in docs with zipline run
2016-08-18 17:37:00 -04:00
Nathan Wolfe 4865ade9b2 ENH: Add fast "vectorized" minute_to_session_label for DatetimeIndex
The new TradingCalendar method is called `minute_index_to_session_labels`.
It takes a DatetimeIndex of in-order market minutes and returns a
DatetimeIndex of the corresponding sessions.

The new method is approximately 100x faster than mapping
`minute_to_session_label` over a large DatetimeIndex.
2016-08-18 17:27:47 -04:00
Eddie Hebert e3bd7e43be MAINT: Remove future/equity distinction.
In the data portal, remove methods that make a distinction between
future and equity asset type. Instead rely on the pricing reader
dispatching.

In support of incoming work which will upsample equity history arrays to
the larger future calendar.

Also, remove perf tracker tests which were using an equity
reader/writer, to be added back in later.
2016-08-18 16:18:32 -04:00
Eddie HebertandGitHub 8834d0c35d Merge pull request #1412 from quantopian/remove-unused-data-portal-members
MAINT: Remove unused data portal members.
2016-08-18 16:14:24 -04:00
Andrew DanielsandGitHub 53ca68e8fb ENH: Pass calendar instance to BcolzMinuteBarWriter (#1406)
* First pass.

* Improvements and fixes

- Update usages of BcolzMinuteBarWriter
- Updates with rebuilt example data
- Expose calendar from BcolzMinuteBarMetadata instead of calendar_name
- Keep market_opens and market_closes in metadata for compatibility

* Store start_session and end_session in minute bcolz metadata

- start_session replaces first_trading_day
- Add end_session to limit to correct days

* For last_available_dt, get last close from calendar to maintain tz

* Bumps version and handles earlier versionson read

* Rebuilt example data on python 3

* Indicate metadata fields that are deprecated
2016-08-18 15:41:26 -04:00
Eddie HebertandGitHub a36766f1af Merge pull request #1411 from quantopian/add-htmlcov-to-gitignore
TST: Add coverage output to gitignore.
2016-08-18 15:07:15 -04:00
Eddie HebertandGitHub 04bf2f0b5e Merge pull request #1410 from quantopian/rename-history-loader
MAINT: Remove equity from history loader classname
2016-08-18 14:48:28 -04:00
Eddie Hebert 6c90a7c08b MAINT: Remove unused data portal members.
Remove members which are not referred to.
2016-08-18 14:38:35 -04:00
Eddie Hebert 2a45bd1829 TST: Add coverage output to gitignore.
Ignore `htmlcov` directory created by `coverage html`.
2016-08-18 14:11:26 -04:00
Eddie Hebert 1d22fab127 MAINT: Remove equity from history loader classname
Prepare for using history loaders with both equity and future data,
2016-08-18 14:10:00 -04:00
Eddie HebertandGitHub c482a7cd59 Merge pull request #1405 from quantopian/resample-session-from-minute
ENH: Session bar reader resampled from minute data
2016-08-18 13:26:24 -04:00
Scott SandersonandGitHub 1c0d407357 Merge pull request #1394 from quantopian/downsample
Add Generic Downsampling to Pipeline
2016-08-18 12:15:54 -04:00
Eddie Hebert f14fcd9b07 ENH: Session bar reader resampled from minute data
Implement a `SessionBarReader` which uses a minute bar reader as a
backing source, resampling the minute bars into the box around the
corresponding session data.

Also, add future/CME test cases to resample suite.
2016-08-18 11:37:42 -04:00
Scott Sanderson bdc72ec4c0 BUG: Fix broken graph visualizations. 2016-08-18 11:07:17 -04:00
Eddie HebertandGitHub 9e0e2c26a5 Merge pull request #1404 from quantopian/session-bar-fixup
MAINT: Use session bar reader interface.
2016-08-18 10:04:46 -04:00
Richard Frank 1226286cab DOC: Replace run_algo.py in docs with zipline run 2016-08-17 21:54:56 -04:00
Scott Sanderson c5a3dae267 BUG: Supply a module for Downsampled terms. 2016-08-17 19:48:33 -04:00
Scott Sanderson 0f5784ab53 BUG: Fix nondeterministic failure from sorting. 2016-08-17 19:48:33 -04:00
Scott Sanderson ecfe33b65b BLD: Ignore numpy_utils.py doctests on windows.
They fail because of 32/64-bit issues.
2016-08-17 19:48:33 -04:00
Richard FrankandGitHub 11f654a688 Merge pull request #1403 from quantopian/keep-last-zero
BUG: Fixes should_clean for keep_last=0
2016-08-17 19:05:31 -04:00
Richard Frank cbcb71bbad BUG: Fixes should_clean for keep_last=0 2016-08-17 18:18:01 -04:00
Scott Sanderson c53ef150ad BUG: Force iterator for py3. 2016-08-17 16:52:09 -04:00
Scott Sanderson a66731b9f3 BUG/TEST: Fix test assertion in py3. 2016-08-17 16:52:09 -04:00
Scott Sanderson 5fe60c76a7 BUG: Fix broken fixture resolution.
Make sure that WithDefaultDateBounds is last in everyone's mro().
2016-08-17 16:52:09 -04:00
Scott Sanderson 115f055c83 MAINT: Clean up downsampling boilerplate.
Consolidate docs and mixin applications into one place.
2016-08-17 16:52:09 -04:00
Scott Sanderson 8fa51bdaab MAINT: Use numpy_utils.as_column in more places. 2016-08-17 16:52:09 -04:00
Scott Sanderson d917a64d45 ENH: Add non-windowed downsampling. 2016-08-17 16:52:09 -04:00
Scott Sanderson a9b5b2ac2f DOC: Docstring cleanups. 2016-08-17 16:52:09 -04:00
Scott Sanderson 5f686173f1 STY: Flake8 cleanup. 2016-08-17 16:52:09 -04:00
Scott Sanderson 91276c7274 ENH: Add support for downsampling.
Adds a new ``downsample`` method to all computable terms.  Computable
terms (Filters, Factors, and Classifiers) can be downsampled to yearly,
quarterly, monthly, or weekly frequency.

The result of ``term.downsample`` is a new term of the same
family (Filter/Factor/Classifier) as ``term``.  The downsampled term
computes by delegating to the original term; repeatedly calling its
``compute`` method with length-1 date ranges.

Downsampled terms take advantage of a new ``compute_extra_rows`` Term
method, which allows terms to dynamically request that additional extra
rows of themselves be computed based on the dates for which they're
being computed.  This ensures, for example, that a monthly-downsampled
term always computes at the start of a month, even when a
naively-calculated pipeline window would end in the middle of the month.
2016-08-17 16:52:09 -04:00
Scott Sanderson 2d02431e6d MAINT: Add alt-constructor for NoFurtherDataError. 2016-08-17 16:52:09 -04:00
Scott Sanderson 0f4964fdfa MAINT: Clean up WithTradingSessions.
- Add WithDefaultDateBounds, since we use alias('START_DATE') and
  alias ('END_DATE').

- Fix copypasta in assertion.
2016-08-17 16:52:09 -04:00
Scott Sanderson fecfca9c59 ENH: Add numpy_utils.changed_locations. 2016-08-17 16:52:09 -04:00
Scott Sanderson 10ab8dc875 MAINT: Remove double import. 2016-08-17 16:52:09 -04:00
Scott Sanderson 1e7b566ed7 MAINT: Add nearest_unequal_elements.. 2016-08-17 16:52:09 -04:00
Scott Sanderson 1444a78330 MAINT: Refactor in prep for downsampled terms.
- Split out extra_rows handling into an `ExecutionPlan` subclass.
  `ExecutionPlan` now requires the dates and calendar against which a
  set of terms will be computed, and now defers to a term's
  `compute_extra_rows` method when deciding how many extra rows are
  required to compute for that term. This will allow downsampled terms
  to request enough extra rows to guarantee that we can maintain consistent
  calculation dates.

  As a consequence of the above, `TermGraph` now only deals with logical
  dependencies, not with metadata surrounding extra row calculations.
  This means that TermGraph can be used to generate dependency
  visualizations in interactive contexts where we don't yet have a
  calendar or start/end dates.

- Refactored test_{filter,factor,classifier} to use check_terms instead
  of run_graph.  This makes it easier to make changes to TermGraph,
  since the testing interface is now to simply provide a dict of terms.

- Refactored BasePipelineTestCase to use fixtures to create an asset
  finder.  This fixes a potential leak of the test's asset db, which was
  not being explicitly cleaned up.

- Refactored test_technical to use BasePipelineTestCase.

- Added a new special term, `InputDates()`, which can be used to request
  date labels for inputs.  Like `AssetExists`, `InputDates` is provided
  in the initial workspace by default.

- Added a default (failing) `_compute` method to `AssetExists` which
  provides a more useful error than AttributeError.
2016-08-17 16:52:09 -04:00
Scott Sanderson 62d69db7f6 MAINT: Remove empty inputs from BoundColumn.
They belong on LoadableTerm instead.
2016-08-17 16:52:09 -04:00
Scott Sanderson 5107906413 ENH: Add as_column to numpy_utils. 2016-08-17 16:52:09 -04:00
Scott Sanderson 765f9b6d57 MAINT: Improve/test errors for insufficient data. 2016-08-17 16:52:09 -04:00
Scott Sanderson 4c59857e1f DOC: Add a docstring for RecarrayField. 2016-08-17 16:52:09 -04:00
Scott Sanderson 14a95449ca DOC: Clarify how AssetExists() is special. 2016-08-17 16:52:09 -04:00
Scott Sanderson b6bacd2815 DOC: Fix typo in docstring. 2016-08-17 16:52:09 -04:00
Eddie Hebert 5723976e56 MAINT: Use session bar reader interface.
Replace `DailyBarReader` with `SessionBarReader`.

This was intended to go with the patch that added the `SessionBarReader`
abstract base class.

Also, added `trading_calendar` property decorator.
2016-08-17 14:30:48 -04:00
Andrew DanielsandGitHub 08a03edad7 MAINT: Use TradingCalendar objects for bundles (#1397)
* MAINT: Use TradingCalendar objects for bundles

Instead of trading days, opens, and closes, register now takes a
TradingCalendar object, along with a start_session and end_session. The
ingest function is now passed these values instead as well.

* Accept calendar name in addition to the actual object

* Updates bundles documentation for changes

* Fix typo in docs

* Use class formatting

* Force start_session and end_session within the bounds of the calendar

* Use UTC timestamps in test_core

* Document Trading Calendar API in appendix.rst
2016-08-17 13:37:07 -04:00
Eddie HebertandGitHub 9bd16aa313 Merge pull request #1401 from quantopian/session-bar-interface
MAINT: Factor out session bar reader interface.
2016-08-17 12:30:17 -04:00
Eddie Hebert ce717a1061 MAINT: Factor out session bar reader interface.
In preparation for making a resampling session bar reader, make an
abstract base class with the methods currently used by consumers of the
reader; which should assist in making a drop-in replacement of the daily
bar reader.

While pulling out the interface, it does appear that `spot_price` and
the minute bar reader's `get_value` are the same method but by different
names, showing that there may be room for having both `MinuteBarReader`
and `SessionBarReader` sharing a common `BarReader` interface.
2016-08-17 11:12:39 -04:00
Eddie HebertandGitHub 5a3588875a Merge pull request #1399 from quantopian/move-resample-code
TST: Share resample test cases.
2016-08-17 10:25:39 -04:00
Scott SandersonandGitHub 19429b9ad8 Merge pull request #1398 from quantopian/validate-attach-pipeline
ENH: Add input validation to attach_pipeline.
2016-08-16 19:49:31 -04:00
Scott Sanderson c7bd0d06e2 ENH: Add input validation to attach_pipeline. 2016-08-16 15:53:20 -04:00
Eddie Hebert 9685f3077a TST: Share resample test cases.
Also, move `DailyHistoryAggregator` to `resample` module, so that tools
for converting from minute to session bars are collocated.

This patch is in preparation of adding a daily bar reader which
resamples minute data, which will be located in the `resample` module
and share the test cases and expected results in `test_resample`.
2016-08-16 15:44:32 -04:00
Eddie HebertandGitHub 369eedf583 Merge pull request #1391 from quantopian/minute-bar-interface
MAINT: Define minute bar reader interface.
2016-08-15 22:34:40 -04:00
Andrew DanielsandGitHub 3136ef3f93 BUG: Fixes asset writer to the select the latest asset to hold a sid (#1392)
* BUG: Fixes asset writer to the select the latest asset to hold a sid

When constructing the asset_info dataframe, we were previously taking
the first symbol/sid pair to include, when we should be taking the most
recent.

* Ensure groups are sorted by increasing end_date

* Updates test_lookup_symbol_change_ticker to also cover asset_name
2016-08-15 20:38:02 -04:00
Eddie Hebert 60f65cb8ce MAINT: Define minute bar reader interface.
Define the minute bar interface and make the `BcolzMinuteBarReader`
implement that interface.
2016-08-15 19:06:02 -04:00
Jean BredecheandGitHub 90a8ea2df3 Merge pull request #1390 from quantopian/revert-can-trade-behavior-for-now
BUG: Temporarily commenting out new can_trade functionality until we sort out downstream dependencies.
2016-08-15 11:22:46 -07:00
Jean Bredeche 34ec70abec BUG: Temporarily commenting out new can_trade functionality until we sort out downstream dependencies. 2016-08-13 21:46:00 -04:00
25 changed files with 3114 additions and 68 deletions
+4
View File
@@ -78,3 +78,7 @@ zipline.iml
./data
TAGS
python2
python3
scratch
+1
View File
@@ -79,6 +79,7 @@ __all__ = [
'gens',
'run_algorithm',
'utils',
'exchange',
]
from ._version import get_versions
+78 -26
View File
@@ -28,9 +28,9 @@ except NameError:
'--strict-extensions/--non-strict-extensions',
is_flag=True,
help='If --strict-extensions is passed then catalyst will not run if it'
' cannot load all of the specified extensions. If this is not passed or'
' --non-strict-extensions is passed then the failure will be logged but'
' execution will continue.',
' cannot load all of the specified extensions. If this is not passed or'
' --non-strict-extensions is passed then the failure will be logged but'
' execution will continue.',
)
@click.option(
'--default-extension/--no-default-extension',
@@ -64,6 +64,7 @@ def extract_option_object(option):
option_object : click.Option
The option object that this decorator will create.
"""
@option
def opt():
pass
@@ -95,7 +96,9 @@ def ipython_only(option):
def _(*args, **kwargs):
kwargs[argname] = None
return f(*args, **kwargs)
return _
return d
@@ -117,9 +120,9 @@ def ipython_only(option):
'--define',
multiple=True,
help="Define a name to be bound in the namespace before executing"
" the algotext. For example '-Dname=value'. The value may be any python"
" expression. These are evaluated in order so they may refer to previously"
" defined names.",
" the algotext. For example '-Dname=value'. The value may be any python"
" expression. These are evaluated in order so they may refer to previously"
" defined names.",
)
@click.option(
'--data-frequency',
@@ -149,7 +152,7 @@ def ipython_only(option):
default=pd.Timestamp.utcnow(),
show_default=False,
help='The date to lookup data on or before.\n'
'[default: <current-time>]'
'[default: <current-time>]'
)
@click.option(
'-s',
@@ -170,7 +173,7 @@ def ipython_only(option):
metavar='FILENAME',
show_default=True,
help="The location to write the perf data. If this is '-' the perf will"
" be written to stdout.",
" be written to stdout.",
)
@click.option(
'--print-algo/--no-print-algo',
@@ -178,12 +181,41 @@ def ipython_only(option):
default=False,
help='Print the algorithm to stdout.',
)
@click.option(
'-s',
'--start',
type=Date(tz='utc', as_timestamp=True),
help='The start date of the simulation.',
)
@ipython_only(click.option(
'--local-namespace/--no-local-namespace',
is_flag=True,
default=None,
help='Should the algorithm methods be resolved in the local namespace.'
))
@click.option(
'--live/--no-live',
is_flag=True,
default=False,
help='Enable live trading.',
)
@click.option(
'-x',
'--exchange-name',
type=click.Choice({'bitfinex'}),
help='The name of the exchange (supported: bitfinex).',
)
@click.option(
'-n',
'--algo-name',
help='A label assigned to the algorithm for tracking purposes.',
)
@click.option(
'-c',
'--reference-currency',
help='The reference currency used to calculate statistics '
'(e.g. usd, btc, eth).',
)
@click.pass_context
def run(ctx,
algofile,
@@ -197,21 +229,37 @@ def run(ctx,
end,
output,
print_algo,
local_namespace):
local_namespace,
live,
exchange_name,
algo_namespace,
base_currency):
"""Run a backtest for the given algorithm.
"""
# check that the start and end dates are passed correctly
if start is None and end is None:
# check both at the same time to avoid the case where a user
# does not pass either of these and then passes the first only
# to be told they need to pass the second argument also
ctx.fail(
"must specify dates with '-s' / '--start' and '-e' / '--end'",
)
if start is None:
ctx.fail("must specify a start date with '-s' / '--start'")
if end is None:
ctx.fail("must specify an end date with '-e' / '--end'")
if live:
if exchange_name is None:
ctx.fail("must specify an exchange name '-x' in live execution "
"mode '--live'")
if algo_namespace is None:
ctx.fail("must specify an algorithm name '-n' in live execution "
"mode '--live'")
if base_currency is None:
ctx.fail("must specify a reference currency '-c' in live "
"execution mode '--live'")
else:
# check that the start and end dates are passed correctly
if start is None and end is None:
# check both at the same time to avoid the case where a user
# does not pass either of these and then passes the first only
# to be told they need to pass the second argument also
ctx.fail(
"must specify dates with '-s' / '--start' and '-e' / '--end'",
)
if start is None:
ctx.fail("must specify a start date with '-s' / '--start'")
if end is None:
ctx.fail("must specify an end date with '-e' / '--end'")
if (algotext is not None) == (algofile is not None):
ctx.fail(
@@ -238,6 +286,10 @@ def run(ctx,
print_algo=print_algo,
local_namespace=local_namespace,
environ=os.environ,
live=live,
exchange=exchange_name,
algo_namespace=algo_namespace,
base_currency=base_currency
)
if output == '-':
@@ -265,11 +317,11 @@ def catalyst_magic(line, cell=None):
'--algotext', cell,
'--output', os.devnull, # don't write the results by default
] + ([
# these options are set when running in line magic mode
# set a non None algo text to use the ipython user_ns
'--algotext', '',
'--local-namespace',
] if cell is None else []) + line.split(),
# these options are set when running in line magic mode
# set a non None algo text to use the ipython user_ns
'--algotext', '',
'--local-namespace',
] if cell is None else []) + line.split(),
'%s%%catalyst' % ((cell or '') and '%'),
# don't use system exit and propogate errors to the caller
standalone_mode=False,
+2
View File
@@ -1138,6 +1138,8 @@ class TradingAlgorithm(object):
freq = self.sim_params.data_frequency
freq = self.sim_params.data_frequency
date_rule = date_rule or date_rules.every_day()
if freq is 'daily':
# ignore time rule in daily mode
+79
View File
@@ -0,0 +1,79 @@
from catalyst.utils.run_algo import run_algorithm
from datetime import datetime
import pytz
from catalyst.api import (
order_target_value,
symbol,
record,
cancel_order,
get_open_orders,
)
def initialize(context):
context.ASSET_NAME = 'USDT_BTC'
context.TARGET_HODL_RATIO = 0.8
context.RESERVE_RATIO = 1.0 - context.TARGET_HODL_RATIO
# For all trading pairs in the poloniex bundle, the default denomination
# currently supported by Catalyst is 1/1000th of a full coin. Use this
# constant to scale the price of up to that of a full coin if desired.
context.TICK_SIZE = 1000.0
context.is_buying = True
context.asset = symbol(context.ASSET_NAME)
context.i = 0
def handle_data(context, data):
context.i += 1
print 'i:', context.i
starting_cash = context.portfolio.starting_cash
target_hodl_value = context.TARGET_HODL_RATIO * starting_cash
reserve_value = context.RESERVE_RATIO * starting_cash
# Cancel any outstanding orders
orders = get_open_orders(context.asset) or []
for order in orders:
cancel_order(order)
# Stop buying after passing the reserve threshold
cash = context.portfolio.cash
if cash <= reserve_value:
context.is_buying = False
# Retrieve current asset price from pricing data
price = data[context.asset].price
# Check if still buying and could (approximately) afford another purchase
if context.is_buying and cash > price:
# Place order to make position in asset equal to target_hodl_value
order_target_value(
context.asset,
target_hodl_value,
limit_price=price * 1.1,
stop_price=price * 0.9,
)
record(
price=price,
cash=cash,
starting_cash=context.portfolio.starting_cash,
leverage=context.account.leverage,
)
start = datetime(2015, 3, 1, 0, 0, 0, 0, pytz.utc)
end = datetime(2017, 6, 28, 0, 0, 0, 0, pytz.utc)
run_algorithm(
initialize=initialize,
handle_data=handle_data,
start=start,
end=end,
capital_base=100000,
bundle='poloniex'
)
+155
View File
@@ -0,0 +1,155 @@
import talib
from logbook import Logger
from catalyst.api import (
order,
order_target_percent,
symbol,
record,
get_open_orders,
)
from catalyst.utils.run_algo import run_algorithm
algo_namespace = 'buy_the_dip_live'
log = Logger(algo_namespace)
def initialize(context):
log.info('initializing algo')
context.ASSET_NAME = 'XRP_USD'
context.asset = symbol(context.ASSET_NAME)
context.TARGET_POSITIONS = 5000
context.PROFIT_TARGET = 0.1
context.SLIPPAGE_ALLOWED = 0.02
context.retry_check_open_orders = 10
context.retry_update_portfolio = 10
context.retry_order = 5
context.errors = []
pass
def _handle_data(context, data):
prices = data.history(
context.asset,
fields='price',
bar_count=20,
frequency='15m'
)
rsi = talib.RSI(prices.values, timeperiod=14)[-1]
log.info('got rsi: {}'.format(rsi))
# Buying more when RSI is low, this should lower our cost basis
if rsi <= 30:
buy_increment = 50
elif rsi <= 40:
buy_increment = 20
elif rsi <= 70:
buy_increment = 5
else:
buy_increment = None
cash = context.portfolio.cash
log.info('base currency available: {cash}'.format(cash=cash))
price = data.current(context.asset, 'price')
log.info('got price {price}'.format(price=price))
record(
price=price,
rsi=rsi,
)
orders = get_open_orders(context.asset)
if orders:
log.info('skipping bar until all open orders execute')
return
is_buy = False
cost_basis = None
if context.asset in context.portfolio.positions:
position = context.portfolio.positions[context.asset]
cost_basis = position.cost_basis
log.info(
'found {amount} positions with cost basis {cost_basis}'.format(
amount=position.amount,
cost_basis=cost_basis
)
)
if position.amount >= context.TARGET_POSITIONS:
log.info('reached positions target: {}'.format(position.amount))
return
if price < cost_basis:
is_buy = True
elif position.amount > 0 and \
price > cost_basis * (1 + context.PROFIT_TARGET):
profit = (price * position.amount) - (cost_basis * position.amount)
log.info('closing position, taking profit: {}'.format(profit))
order_target_percent(
asset=context.asset,
target=0,
limit_price=price * (1 - context.SLIPPAGE_ALLOWED),
)
else:
log.info('no buy or sell opportunity found')
else:
is_buy = True
if is_buy:
if buy_increment is None:
log.info('the rsi is too high to consider buying {}'.format(rsi))
return
if price * buy_increment > cash:
log.info('not enough base currency to consider buying')
return
log.info(
'buying position cheaper than cost basis {} < {}'.format(
price,
cost_basis
)
)
order(
asset=context.asset,
amount=buy_increment,
limit_price=price * (1 + context.SLIPPAGE_ALLOWED)
)
def handle_data(context, data):
log.info('handling bar {}'.format(data.current_dt))
# try:
_handle_data(context, data)
# except Exception as e:
# log.warn('aborting the bar on error {}'.format(e))
# context.errors.append(e)
log.info('completed bar {}, total execution errors {}'.format(
data.current_dt,
len(context.errors)
))
if len(context.errors) > 0:
log.info('the errors:\n{}'.format(context.errors))
def analyze(context, stats):
log.info('the full stats:\n{}'.format(stats.head()))
pass
run_algorithm(
initialize=initialize,
handle_data=handle_data,
analyze=analyze,
exchange_name='bitfinex',
live=True,
algo_namespace=algo_namespace,
base_currency='usd'
)
View File
+437
View File
@@ -0,0 +1,437 @@
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import signal
import sys
import pickle
from datetime import timedelta
from time import sleep
from os import listdir
from os.path import isfile, join
import logbook
import pandas as pd
import catalyst.protocol as zp
from catalyst.algorithm import TradingAlgorithm
from catalyst.data.minute_bars import BcolzMinuteBarWriter, \
BcolzMinuteBarReader
from catalyst.errors import OrderInBeforeTradingStart
from catalyst.exchange.exchange_clock import ExchangeClock
from catalyst.exchange.exchange_errors import (
ExchangeRequestError,
ExchangePortfolioDataError,
ExchangeTransactionError
)
from catalyst.exchange.exchange_utils import get_exchange_minute_writer_root, \
save_algo_object, get_algo_object, get_algo_folder
from catalyst.finance.performance.period import calc_period_stats
from catalyst.gens.tradesimulation import AlgorithmSimulator
from catalyst.utils.api_support import (
api_method,
disallowed_in_before_trading_start)
from catalyst.utils.input_validation import error_keywords
log = logbook.Logger("ExchangeTradingAlgorithm")
class ExchangeAlgorithmExecutor(AlgorithmSimulator):
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
class ExchangeTradingAlgorithm(TradingAlgorithm):
def __init__(self, *args, **kwargs):
self.exchange = kwargs.pop('exchange', None)
self.algo_namespace = kwargs.pop('algo_namespace', None)
self.orders = {}
self.is_running = True
self.retry_check_open_orders = 5
self.retry_update_portfolio = 5
self.retry_get_open_orders = 5
self.retry_order = 2
self.retry_delay = 5
super(self.__class__, self).__init__(*args, **kwargs)
self._create_minute_writer()
signal.signal(signal.SIGINT, self.signal_handler)
log.info('exchange trading algorithm successfully initialized')
def _create_minute_writer(self):
root = get_exchange_minute_writer_root(self.exchange.name)
filename = os.path.join(root, 'metadata.json')
if os.path.isfile(filename):
writer = BcolzMinuteBarWriter.open(
root, self.sim_params.end_session)
else:
writer = BcolzMinuteBarWriter(
rootdir=root,
calendar=self.trading_calendar,
minutes_per_day=1440,
start_session=self.sim_params.start_session,
end_session=self.sim_params.end_session,
write_metadata=True
)
self.exchange.minute_writer = writer
self.exchange.minute_reader = BcolzMinuteBarReader(root)
def signal_handler(self, signal, frame):
self.is_running = False
log.info('You pressed Ctrl+C!')
stats = None
try:
algo_folder = get_algo_folder(self.algo_namespace)
folder = join(algo_folder, 'daily_perf')
files = [f for f in listdir(folder) if isfile(join(folder, f))]
daily_perf_list = []
for item in files:
filename = join(folder, item)
with open(filename, 'rb') as handle:
daily_perf_list.append(pickle.load(handle))
stats = pd.DataFrame(daily_perf_list)
stats.set_index('period_close', drop=True, inplace=True)
except Exception as e:
log.warn('Unable to compute daily stats: {}'.format(e))
self.analyze(stats)
sys.exit(0)
def _create_clock(self):
# The calendar's execution times are the minutes over which we actually
# want to run the clock. Typically the execution times simply adhere to
# the market open and close times. In the case of the futures calendar,
# for example, we only want to simulate over a subset of the full 24
# hour calendar, so the execution times dictate a market open time of
# 6:31am US/Eastern and a close of 5:00pm US/Eastern.
# In our case, we are trading around the clock, so the market close
# corresponds to the last minute of the day.
# This method is taken from TradingAlgorithm.
# The clock has been replaced to use RealtimeClock
# TODO: should we apply a time skew? not sure to understand the utility.
return ExchangeClock(
self.sim_params.sessions,
time_skew=self.exchange.time_skew
)
def _create_generator(self, sim_params):
if self.perf_tracker is None:
self.perf_tracker = get_algo_object(
algo_name=self.algo_namespace,
key='perf_tracker'
)
# Call the simulation trading algorithm for side-effects:
# it creates the perf tracker
TradingAlgorithm._create_generator(self, sim_params)
self.trading_client = ExchangeAlgorithmExecutor(
self,
sim_params,
self.data_portal,
self._create_clock(),
self._create_benchmark_source(),
self.restrictions,
universe_func=self._calculate_universe
)
return self.trading_client.transform()
def updated_portfolio(self):
"""
We skip the entire performance tracker business and update the
portfolio directly.
:return:
"""
return self.exchange.portfolio
def updated_account(self):
return self.exchange.account
def _update_portfolio(self, attempt_index=0):
try:
self.exchange.update_portfolio()
# Applying the updated last_sales_price to the positions
# in the performance tracker. This seems a bit redundant
# but it will make sense when we have multiple exchange portfolios
# feeding into the same performance tracker.
tracker = self.perf_tracker.todays_performance.position_tracker
for asset in self.exchange.portfolio.positions:
position = self.exchange.portfolio.positions[asset]
tracker.update_position(
asset=asset,
last_sale_date=position.last_sale_date,
last_sale_price=position.last_sale_price
)
except ExchangeRequestError as e:
log.warn(
'update portfolio attempt {}: {}'.format(attempt_index, e)
)
if attempt_index < self.retry_update_portfolio:
sleep(self.retry_delay)
self._update_portfolio(attempt_index + 1)
else:
raise ExchangePortfolioDataError(
data_type='update-portfolio',
attempts=attempt_index,
error=e
)
def _check_open_orders(self, attempt_index=0):
try:
return self.exchange.check_open_orders()
except ExchangeRequestError as e:
log.warn(
'check open orders attempt {}: {}'.format(attempt_index, e)
)
if attempt_index < self.retry_check_open_orders:
sleep(self.retry_delay)
return self._check_open_orders(attempt_index + 1)
else:
raise ExchangePortfolioDataError(
data_type='order-status',
attempts=attempt_index,
error=e
)
def prepare_period_stats(self, start_dt, end_dt):
"""
Creates a dictionary representing the state of the tracker.
I rewrote this in an attempt to better control the stats.
I don't want things to happen magically through complex logic
pertaining to backtesting.
"""
tracker = self.perf_tracker
period = tracker.todays_performance
pos_stats = period.position_tracker.stats()
period_stats = calc_period_stats(pos_stats, period.ending_cash)
stats = dict(
period_start=tracker.period_start,
period_end=tracker.period_end,
capital_base=tracker.capital_base,
progress=tracker.progress,
ending_value=period.ending_value,
ending_exposure=period.ending_exposure,
capital_used=period.cash_flow,
starting_value=period.starting_value,
starting_exposure=period.starting_exposure,
starting_cash=period.starting_cash,
ending_cash=period.ending_cash,
portfolio_value=period.ending_cash + period.ending_value,
pnl=period.pnl,
returns=period.returns,
period_open=period.period_open,
period_close=period.period_close,
gross_leverage=period_stats.gross_leverage,
net_leverage=period_stats.net_leverage,
short_exposure=pos_stats.short_exposure,
long_exposure=pos_stats.long_exposure,
short_value=pos_stats.short_value,
long_value=pos_stats.long_value,
longs_count=pos_stats.longs_count,
shorts_count=pos_stats.shorts_count,
)
# Merging cumulative risk
stats.update(tracker.cumulative_risk_metrics.to_dict())
# Merging latest recorded variables
stats.update(self.recorded_vars)
stats['positions'] = period.position_tracker.get_positions_list()
# we want the key to be absent, not just empty
# Only include transactions for given dt
stats['transactions'] = dict()
for date in period.processed_transactions:
if start_dt <= date < end_dt:
stats['transactions'][date] = \
period.processed_transactions[date]
stats['orders'] = dict()
for date in period.orders_by_modified:
if start_dt <= date < end_dt:
stats['orders'][date] = \
period.orders_by_modified[date]
return stats
def handle_data(self, data):
if not self.is_running:
return
self._update_portfolio()
transactions = self._check_open_orders()
for transaction in transactions:
self.perf_tracker.process_transaction(transaction)
if self._handle_data:
self._handle_data(self, data)
# Unlike trading controls which remain constant unless placing an
# order, account controls can change each bar. Thus, must check
# every bar no matter if the algorithm places an order or not.
self.validate_account_controls()
try:
# Since the clock runs 24/7, I trying to disable the daily
# Performance tracker and keep only minute and cumulative
self.perf_tracker.update_performance()
# TODO: save for future use?
minute_stats = self.prepare_period_stats(
data.current_dt, data.current_dt + timedelta(minutes=1))
log.debug('the minute performance:\n{}'.format(minute_stats))
today = pd.to_datetime('today', utc=True)
daily_stats = self.prepare_period_stats(
start_dt=today,
end_dt=pd.Timestamp.utcnow()
)
save_algo_object(
algo_name=self.algo_namespace,
key=today.strftime('%Y-%m-%d'),
obj=daily_stats,
rel_path='daily_perf'
)
except Exception as e:
log.warn('unable to calculate performance: {}'.format(e))
try:
save_algo_object(
algo_name=self.algo_namespace,
key='perf_tracker',
obj=self.perf_tracker
)
except Exception as e:
log.warn('unable to save minute perfs to disk: {}'.format(e))
try:
save_algo_object(
algo_name=self.algo_namespace,
key='portfolio_{}'.format(self.exchange.name),
obj=self.exchange.portfolio
)
except Exception as e:
log.warn('unable to save portfolio to disk: {}'.format(e))
def _order(self,
asset,
amount,
limit_price=None,
stop_price=None,
style=None,
attempt_index=0):
try:
return self.exchange.order(asset, amount, limit_price,
stop_price,
style)
except ExchangeRequestError as e:
log.warn(
'order attempt {}: {}'.format(attempt_index, e)
)
if attempt_index < self.retry_order:
sleep(self.retry_delay)
return self._order(
asset, amount, limit_price, stop_price, style,
attempt_index + 1)
else:
raise ExchangeTransactionError(
transaction_type='order',
attempts=attempt_index,
error=e
)
@api_method
@disallowed_in_before_trading_start(OrderInBeforeTradingStart())
def order(self,
asset,
amount,
limit_price=None,
stop_price=None,
style=None):
amount, style = self._calculate_order(asset, amount,
limit_price, stop_price,
style)
order_id = self._order(asset, amount, limit_price, stop_price, style)
order = self.portfolio.open_orders[order_id]
self.perf_tracker.process_order(order)
return order
def round_order(self, amount):
"""
We need fractions with cryptocurrencies
:param amount:
:return:
"""
return amount
@api_method
def batch_market_order(self, share_counts):
raise NotImplementedError()
def _get_open_orders(self, asset=None, attempt_index=0):
try:
return self.exchange.get_open_orders(asset)
except ExchangeRequestError as e:
log.warn(
'open orders attempt {}: {}'.format(attempt_index, e)
)
if attempt_index < self.retry_get_open_orders:
sleep(self.retry_delay)
return self._get_open_orders(asset, attempt_index + 1)
else:
raise ExchangePortfolioDataError(
data_type='open-orders',
attempts=attempt_index,
error=e
)
@error_keywords(sid='Keyword argument `sid` is no longer supported for '
'get_open_orders. Use `asset` instead.')
@api_method
def get_open_orders(self, asset=None):
return self._get_open_orders(asset)
@api_method
def get_order(self, order_id):
return self.exchange.get_order(order_id)
@api_method
def cancel_order(self, order_param):
order_id = order_param
if isinstance(order_param, zp.Order):
order_id = order_param.id
self.exchange.cancel_order(order_id)
@@ -0,0 +1,91 @@
from logbook import Logger
log = Logger('AssetFinderExchange')
class AssetFinderExchange(object):
def __init__(self, exchange):
self.exchange = exchange
self._asset_cache = {}
@property
def sids(self):
"""
This seems to be used to pre-fetch assets.
I don't think that we need this for live-trading.
Leaving the list empty.
"""
return list()
def retrieve_all(self, sids, default_none=False):
"""
Retrieve all assets in `sids`.
Parameters
----------
sids : iterable of int
Assets to retrieve.
default_none : bool
If True, return None for failed lookups.
If False, raise `SidsNotFound`.
Returns
-------
assets : list[Asset or None]
A list of the same length as `sids` containing Assets (or Nones)
corresponding to the requested sids.
Raises
------
SidsNotFound
When a requested sid is not found and default_none=False.
"""
for sid in sids:
if sid in self._asset_cache:
log.info('got asset from cache: {}'.format(sid))
else:
log.info('fetching asset: {}'.format(sid))
return list()
def lookup_symbol(self, symbol, as_of_date, fuzzy=False):
"""Lookup an asset by symbol.
Parameters
----------
symbol : str
The ticker symbol to resolve.
as_of_date : datetime or None
Look up the last owner of this symbol as of this datetime.
If ``as_of_date`` is None, then this can only resolve the equity
if exactly one equity has ever owned the ticker.
fuzzy : bool, optional
Should fuzzy symbol matching be used? Fuzzy symbol matching
attempts to resolve differences in representations for
shareclasses. For example, some people may represent the ``A``
shareclass of ``BRK`` as ``BRK.A``, where others could write
``BRK_A``.
Returns
-------
equity : Asset
The equity that held ``symbol`` on the given ``as_of_date``, or the
only equity to hold ``symbol`` if ``as_of_date`` is None.
Raises
------
SymbolNotFound
Raised when no equity has ever held the given symbol.
MultipleSymbolsFound
Raised when no ``as_of_date`` is given and more than one equity
has held ``symbol``. This is also raised when ``fuzzy=True`` and
there are multiple candidates for the given ``symbol`` on the
``as_of_date``.
"""
log.info('looking up symbol: {}'.format(symbol))
if symbol in self._asset_cache:
return self._asset_cache[symbol]
else:
asset = self.exchange.get_asset(symbol)
self._asset_cache[symbol] = asset
return asset
+647
View File
@@ -0,0 +1,647 @@
import base64
import numpy as np
import hashlib
import hmac
import json
import re
import time
import pandas as pd
import pytz
import requests
import six
from catalyst.assets._assets import Asset
from logbook import Logger
# from websocket import create_connection
from catalyst.exchange.exchange import Exchange
from catalyst.exchange.exchange_errors import (
ExchangeRequestError,
InvalidHistoryFrequencyError
)
from catalyst.finance.execution import (MarketOrder,
LimitOrder,
StopOrder,
StopLimitOrder)
from catalyst.finance.order import Order, ORDER_STATUS
from catalyst.protocol import Account
# Trying to account for REST api instability
# https://stackoverflow.com/questions/15431044/can-i-set-max-retries-for-requests-request
requests.adapters.DEFAULT_RETRIES = 20
BITFINEX_URL = 'https://api.bitfinex.com'
log = Logger('Bitfinex')
warning_logger = Logger('AlgoWarning')
class Bitfinex(Exchange):
def __init__(self, key, secret, base_currency, portfolio=None):
self.url = BITFINEX_URL
self.key = key
self.secret = secret
self.id = 'b'
self.name = 'bitfinex'
self.assets = {}
self.load_assets()
self.base_currency = base_currency
self._portfolio = portfolio
self.minute_writer = None
self.minute_reader = None
def _request(self, operation, data, version='v1'):
payload_object = {
'request': '/{}/{}'.format(version, operation),
'nonce': '{0:f}'.format(time.time() * 1000000),
# convert to string
'options': {}
}
if data is None:
payload_dict = payload_object
else:
payload_dict = payload_object.copy()
payload_dict.update(data)
payload_json = json.dumps(payload_dict)
if six.PY3:
payload = base64.b64encode(bytes(payload_json, 'utf-8'))
else:
payload = base64.b64encode(payload_json)
m = hmac.new(self.secret, payload, hashlib.sha384)
m = m.hexdigest()
# headers
headers = {
'X-BFX-APIKEY': self.key,
'X-BFX-PAYLOAD': payload,
'X-BFX-SIGNATURE': m
}
if data is None:
request = requests.get(
'{url}/{version}/{operation}'.format(
url=self.url,
version=version,
operation=operation
), data={},
headers=headers)
else:
request = requests.post(
'{url}/{version}/{operation}'.format(
url=self.url,
version=version,
operation=operation
),
headers=headers)
return request
def _get_v2_symbol(self, asset):
pair = asset.symbol.split('_')
symbol = 't' + pair[0].upper() + pair[1].upper()
return symbol
def _get_v2_symbols(self, assets):
"""
Workaround to support Bitfinex v2
TODO: Might require a separate asset dictionary
:param assets:
:return:
"""
v2_symbols = []
for asset in assets:
v2_symbols.append(self._get_v2_symbol(asset))
return v2_symbols
def _create_order(self, order_status):
"""
Create a Catalyst order object from a Bitfinex order dictionary
:param order_status:
:return: Order
"""
if order_status['is_cancelled']:
status = ORDER_STATUS.CANCELLED
elif not order_status['is_live']:
log.info('found executed order {}'.format(order_status))
status = ORDER_STATUS.FILLED
else:
status = ORDER_STATUS.OPEN
amount = float(order_status['original_amount'])
filled = float(order_status['executed_amount'])
is_buy = (amount > 0)
price = float(order_status['price'])
order_type = order_status['type']
stop_price = None
limit_price = None
# TODO: is this comprehensive enough?
if order_type.endswith('limit'):
limit_price = price
elif order_type.endswith('stop'):
stop_price = price
executed_price = float(order_status['avg_execution_price'])
# TODO: bitfinex does not specify comission. I could calculate it but not sure if it's worth it.
commission = None
# TODO: zipline likes rounded dates to match statistics, is this ok?
date = pd.Timestamp.utcfromtimestamp(float(order_status['timestamp']))
date = pytz.utc.localize(date)
order = Order(
dt=date,
asset=self.assets[order_status['symbol']],
amount=amount,
stop=stop_price,
limit=limit_price,
filled=filled,
id=order_status['id'],
commission=commission
)
order.status = status
return order, executed_price
def update_portfolio(self):
"""
Update the portfolio cash and position balances based on the
latest ticker prices.
:return:
"""
try:
response = self._request('balances', None)
balances = response.json()
except Exception as e:
raise ExchangeRequestError(error=e)
if 'message' in balances:
raise ExchangeRequestError(
error='unable to fetch balance {}'.format(balances['message'])
)
base_position = None
for position in balances:
if not base_position and position['type'] == 'exchange' \
and position['currency'] == self.base_currency:
base_position = position
if position is None:
raise ValueError(
error='Base currency %s not found in portfolio' % self.base_currency
)
portfolio = self._portfolio
portfolio.cash = float(base_position['available'])
if portfolio.starting_cash is None:
portfolio.starting_cash = portfolio.cash
if portfolio.positions:
assets = portfolio.positions.keys()
tickers = self.tickers(assets)
portfolio.positions_value = 0.0
for ticker in tickers:
# TODO: convert if the position is not in the base currency
position = portfolio.positions[ticker['asset']]
position.last_sale_price = ticker['last_price']
position.last_sale_date = ticker['timestamp']
portfolio.positions_value += \
position.amount * position.last_sale_price
portfolio.portfolio_value = \
portfolio.positions_value + portfolio.cash
@property
def portfolio(self):
"""
Return the Portfolio
:return:
"""
# if self._portfolio is None:
# portfolio = ExchangePortfolio(
# start_date=pd.Timestamp.utcnow()
# )
# self.store.portfolio = portfolio
# self.update_portfolio()
#
# portfolio.starting_cash = portfolio.cash
# else:
# portfolio = self.store.portfolio
return self._portfolio
@property
def account(self):
account = Account()
account.settled_cash = None
account.accrued_interest = None
account.buying_power = None
account.equity_with_loan = None
account.total_positions_value = None
account.total_positions_exposure = None
account.regt_equity = None
account.regt_margin = None
account.initial_margin_requirement = None
account.maintenance_margin_requirement = None
account.available_funds = None
account.excess_liquidity = None
account.cushion = None
account.day_trades_remaining = None
account.leverage = None
account.net_leverage = None
account.net_liquidation = None
return account
@property
def positions(self):
return self.portfolio.positions
@property
def time_skew(self):
# TODO: research the time skew conditions
return pd.Timedelta('0s')
def subscribe_to_market_data(self, symbol):
pass
def get_candles(self, data_frequency, assets, bar_count=None):
"""
Retrieve OHLVC candles from Bitfinex
:param data_frequency:
:param assets:
:param bar_count:
:return:
Available Frequencies
---------------------
'1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D',
'1M'
"""
# TODO: use BcolzMinuteBarReader to read from cache
freq_match = re.match(r'([0-9].*)(m|h|d)', data_frequency, re.M | re.I)
if freq_match:
number = int(freq_match.group(1))
unit = freq_match.group(2)
if unit == 'd':
converted_unit = 'D'
else:
converted_unit = unit
frequency = '{}{}'.format(number, converted_unit)
allowed_frequencies = ['1m', '5m', '15m', '30m', '1h', '3h', '6h',
'12h', '1D', '7D', '14D', '1M']
if frequency not in allowed_frequencies:
raise InvalidHistoryFrequencyError(
frequency=data_frequency
)
elif data_frequency == 'minute':
frequency = '1m'
elif data_frequency == 'daily':
frequency = '1D'
else:
raise InvalidHistoryFrequencyError(
frequency=data_frequency
)
# Making sure that assets are iterable
asset_list = [assets] if isinstance(assets, Asset) else assets
ohlc_list = dict()
for asset in asset_list:
symbol = self._get_v2_symbol(asset)
url = '{url}/v2/candles/trade:{frequency}:{symbol}'.format(
url=self.url,
frequency=frequency,
symbol=symbol
)
if bar_count:
is_list = True
url += '/hist?limit={}'.format(int(bar_count))
else:
is_list = False
url += '/last'
try:
response = requests.get(url)
except Exception as e:
raise ExchangeRequestError(error=e)
if 'error' in response.content:
raise ExchangeRequestError(
error='Unable to retrieve candles: {}'.format(
response.content)
)
candles = response.json()
def ohlc_from_candle(candle):
ohlc = dict(
open=np.float64(candle[1]),
high=np.float64(candle[3]),
low=np.float64(candle[4]),
close=np.float64(candle[2]),
volume=np.float64(candle[5]),
price=np.float64(candle[2]),
last_traded=pd.Timestamp.utcfromtimestamp(
candle[0] / 1000.0),
minute_dt=pd.Timestamp.utcnow().floor('1 min')
)
return ohlc
if is_list:
ohlc_bars = []
# We can to list candles from old to new
for candle in reversed(candles):
ohlc = ohlc_from_candle(candle)
ohlc_bars.append(ohlc)
ohlc_list[asset] = ohlc_bars
else:
ohlc = ohlc_from_candle(candles)
ohlc_list[asset] = ohlc
return ohlc_list[assets] \
if isinstance(assets, Asset) else ohlc_list
def order(self, asset, amount, limit_price, stop_price, style):
"""Place an order.
Parameters
----------
asset : Asset
The asset that this order is for.
amount : int
The amount of shares to order. If ``amount`` is positive, this is
the number of shares to buy or cover. If ``amount`` is negative,
this is the number of shares to sell or short.
limit_price : float, optional
The limit price for the order.
stop_price : float, optional
The stop price for the order.
style : ExecutionStyle, optional
The execution style for the order.
Returns
-------
order_id : str or None
The unique identifier for this order, or None if no order was
placed.
Notes
-----
The ``limit_price`` and ``stop_price`` arguments provide shorthands for
passing common execution styles. Passing ``limit_price=N`` is
equivalent to ``style=LimitOrder(N)``. Similarly, passing
``stop_price=M`` is equivalent to ``style=StopOrder(M)``, and passing
``limit_price=N`` and ``stop_price=M`` is equivalent to
``style=StopLimitOrder(N, M)``. It is an error to pass both a ``style``
and ``limit_price`` or ``stop_price``.
Bitfinex Order Types
--------------------
LIMIT, MARKET, STOP, TRAILING STOP,
EXCHANGE MARKET, EXCHANGE LIMIT, EXCHANGE STOP,
EXCHANGE TRAILING STOP, FOK, EXCHANGE FOK.
See Also
--------
:class:`catalyst.finance.execution.ExecutionStyle`
:func:`catalyst.api.order_value`
:func:`catalyst.api.order_percent`
"""
if amount == 0:
log.warn('skipping order amount of 0')
return None
base_currency = asset.symbol.split('_')[1]
if base_currency.lower() != self.base_currency.lower():
raise NotImplementedError(
'Currency pairs must share their base with the exchange.'
)
is_buy = (amount > 0)
if isinstance(style, MarketOrder):
order_type = 'market'
elif isinstance(style, LimitOrder):
order_type = 'limit'
price = limit_price
elif isinstance(style, StopOrder):
order_type = 'stop'
price = stop_price
elif isinstance(style, StopLimitOrder):
log.warn('using limit order instead of stop/limit')
# TODO: Not sure how to do this with the api. Investigate.
order_type = 'limit'
price = limit_price
else:
raise NotImplementedError('%s orders not available' % style)
log.debug(
'ordering {amount} {symbol} for {price}'.format(
amount=amount,
symbol=asset.symbol,
price=price
)
)
exchange_symbol = self.get_symbol(asset)
req = dict(
symbol=exchange_symbol,
amount=str(float(abs(amount))),
price=str(float(price)),
side='buy' if is_buy else 'sell',
type='exchange ' + order_type, # TODO: support margin trades
exchange=self.name,
is_hidden=False,
is_postonly=False,
use_all_available=0,
ocoorder=False,
buy_price_oco=0,
sell_price_oco=0
)
date = pd.Timestamp.utcnow()
try:
response = self._request('order/new', req)
exchange_order = response.json()
except Exception as e:
raise ExchangeRequestError(error=e)
if 'message' in exchange_order:
raise ExchangeRequestError(
error='unable to create Bitfinex order {}'.format(
exchange_order['message'])
)
order_id = exchange_order['id']
order = Order(
dt=date,
asset=asset,
amount=amount,
stop=style.get_stop_price(is_buy),
limit=style.get_limit_price(is_buy),
id=order_id
)
# TODO: is this required?
order.broker_order_id = order_id
self.portfolio.create_order(order)
return order_id
def get_open_orders(self, asset=None):
"""Retrieve all of the current open orders.
Parameters
----------
asset : Asset
If passed and not None, return only the open orders for the given
asset instead of all open orders.
Returns
-------
open_orders : dict[list[Order]] or list[Order]
If no asset is passed this will return a dict mapping Assets
to a list containing all the open orders for the asset.
If an asset is passed then this will return a list of the open
orders for this asset.
"""
try:
response = self._request('orders', None)
order_statuses = response.json()
except Exception as e:
raise ExchangeRequestError(error=e)
if 'message' in order_statuses:
raise ExchangeRequestError(
error='Unable to retrieve open orders: {}'.format(
order_statuses['message'])
)
orders = list()
for order_status in order_statuses:
order, = self._create_order(order_status)
if asset is None or asset == order.sid:
orders.append(order)
return orders
def get_order(self, order_id):
"""Lookup an order based on the order id returned from one of the
order functions.
Parameters
----------
order_id : str
The unique identifier for the order.
Returns
-------
order : Order
The order object.
"""
try:
response = self._request(
'order/status', {'order_id': int(order_id)})
order_status = response.json()
except Exception as e:
raise ExchangeRequestError(error=e)
if 'message' in order_status:
raise ExchangeRequestError(
error='Unable to retrieve order status: {}'.format(
order_status['message'])
)
return self._create_order(order_status)
def cancel_order(self, order_param):
"""Cancel an open order.
Parameters
----------
order_param : str or Order
The order_id or order object to cancel.
"""
order_id = order_param.id \
if isinstance(order_param, Order) else order_param
try:
response = self._request('order/cancel', {'order_id': order_id})
status = response.json()
except Exception as e:
raise ExchangeRequestError(error=e)
if 'message' in status:
raise ExchangeRequestError(
error='Unable to cancel order: {} {}'.format(
order_id, status['message'])
)
def tickers(self, assets):
"""
Fetch ticket data for assets
https://docs.bitfinex.com/v2/reference#rest-public-tickers
:param assets:
:return:
"""
symbols = self._get_v2_symbols(assets)
log.debug('fetching tickers {}'.format(symbols))
try:
response = requests.get(
'{url}/v2/tickers?symbols={symbols}'.format(
url=self.url,
symbols=','.join(symbols),
)
)
except Exception as e:
raise ExchangeRequestError(error=e)
if 'error' in response.content:
raise ExchangeRequestError(
error='Unable to retrieve tickers: {}'.format(
response.content)
)
tickers = response.json()
formatted_tickers = []
for index, ticker in enumerate(tickers):
if not len(ticker) == 11:
raise ExchangeRequestError(
error='Invalid ticker in response: {}'.format(ticker)
)
tick = dict(
asset=assets[index],
timestamp=pd.Timestamp.utcnow(),
bid=ticker[1],
ask=ticker[3],
last_price=ticker[7],
low=ticker[10],
high=ticker[9],
volume=ticker[8],
)
formatted_tickers.append(tick)
log.debug('got tickers {}'.format(formatted_tickers))
return formatted_tickers
+121
View File
@@ -0,0 +1,121 @@
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from time import sleep
from logbook import Logger
from catalyst.data.data_portal import DataPortal
from catalyst.exchange.exchange_errors import (
ExchangeRequestError,
ExchangeBarDataError
)
log = Logger('DataPortalExchange')
class DataPortalExchange(DataPortal):
def __init__(self, exchange, *args, **kwargs):
self.exchange = exchange
# TODO: put somewhere accessible by each algo
self.retry_get_history_window = 5
self.retry_get_spot_value = 5
self.retry_delay = 5
super(DataPortalExchange, self).__init__(*args, **kwargs)
def _get_history_window(self,
assets,
end_dt,
bar_count,
frequency,
field,
data_frequency,
ffill=True,
attempt_index=0):
try:
return self.exchange.get_history_window(
assets,
end_dt,
bar_count,
frequency,
field,
data_frequency,
ffill)
except ExchangeRequestError as e:
log.warn(
'get history attempt {}: {}'.format(attempt_index, e)
)
if attempt_index < self.retry_get_history_window:
sleep(self.retry_delay)
return self._get_history_window(assets,
end_dt,
bar_count,
frequency,
field,
data_frequency,
ffill,
attempt_index + 1)
else:
raise ExchangeBarDataError(
data_type='history',
attempts=attempt_index,
error=e
)
def get_history_window(self,
assets,
end_dt,
bar_count,
frequency,
field,
data_frequency,
ffill=True):
return self._get_history_window(assets,
end_dt,
bar_count,
frequency,
field,
data_frequency,
ffill)
def _get_spot_value(self, assets, field, dt, data_frequency,
attempt_index=0):
try:
return self.exchange.get_spot_value(assets, field, dt,
data_frequency)
except ExchangeRequestError as e:
log.warn(
'get spot value attempt {}: {}'.format(attempt_index, e)
)
if attempt_index < self.retry_get_spot_value:
sleep(self.retry_delay)
return self._get_spot_value(assets, field, dt, data_frequency,
attempt_index + 1)
else:
raise ExchangeBarDataError(
data_type='spot',
attempts=attempt_index,
error=e
)
def get_spot_value(self, assets, field, dt, data_frequency):
return self._get_spot_value(assets, field, dt, data_frequency)
def get_adjusted_value(self, asset, field, dt,
perspective_dt,
data_frequency,
spot_value=None):
# TODO: does this pertain to cryptocurrencies?
raise NotImplementedError("get_adjusted_value is not implemented yet!")
+489
View File
@@ -0,0 +1,489 @@
import abc
import random
from time import sleep
import collections
from abc import ABCMeta, abstractmethod, abstractproperty
from datetime import timedelta
import numpy as np
import pandas as pd
from catalyst.assets._assets import Asset
from logbook import Logger
from catalyst.data.data_portal import BASE_FIELDS
from catalyst.errors import (
SymbolNotFound,
)
from catalyst.finance.order import ORDER_STATUS
from catalyst.finance.transaction import Transaction
from catalyst.exchange.exchange_utils import get_exchange_symbols
log = Logger('Exchange')
class Exchange:
__metaclass__ = ABCMeta
def __init__(self):
self.name = None
self.trading_pairs = None
self.assets = {}
self._portfolio = None
self.minute_writer = None
self.minute_reader = None
@abstractmethod
def subscribe_to_market_data(self, symbol):
pass
@abstractproperty
def positions(self):
pass
@abstractproperty
def update_portfolio(self):
pass
@abstractproperty
def portfolio(self):
pass
@abstractproperty
def account(self):
pass
@abstractproperty
def time_skew(self):
pass
def get_symbol(self, asset):
"""
Get the exchange specific symbol of the given asset.
:param asset: Asset
:return: symbol: str
"""
symbol = None
for key in self.assets:
if not symbol and self.assets[key].symbol == asset.symbol:
symbol = key
if not symbol:
raise ValueError('Currency %s not supported by exchange %s' %
(asset['symbol'], self.name))
return symbol
def get_symbols(self, assets):
"""
Get a list of symbols corresponding to each given asset.
:param assets: Asset[]
:return:
"""
symbols = []
for asset in assets:
symbols.append(self.get_symbol(asset))
return symbols
def get_asset(self, symbol):
"""
Find an Asset on the current exchange based on its Catalyst symbol
:param symbol: the [target]_[base] currency pair symbol
:return: Asset
"""
asset = None
for key in self.assets:
if not asset and self.assets[key].symbol.lower() == symbol.lower():
asset = self.assets[key]
if not asset:
raise SymbolNotFound('Asset not found: %s' % symbol)
return asset
def load_assets(self):
"""
Populate the 'assets' attribute with a dictionary of Assets.
The key of the resulting dictionary is the exchange specific
currency pair symbol. The universal symbol is contained in the
'symbol' attribute of each asset.
Notes
-----
The sid of each asset is calculated based on a numeric hash of the
universal symbol. This simple approach avoids maintaining a mapping
of sids.
This method can be overridden if an exchange offers equivalent data
via its api.
"""
symbol_map = get_exchange_symbols(self.name)
for exchange_symbol in symbol_map:
asset = symbol_map[exchange_symbol]
symbol = asset['symbol']
asset_name = ' / '.join(symbol.split('_')).upper()
asset_obj = Asset(
symbol=symbol,
asset_name=asset_name,
sid=abs(hash(symbol)) % (10 ** 4),
exchange=self.name,
start_date=pd.to_datetime(asset['start_date'], utc=True),
end_date=pd.Timestamp.utcnow() + timedelta(minutes=300000),
)
self.assets[exchange_symbol] = asset_obj
def check_open_orders(self):
"""
Loop through the list of open orders in the Portfolio object.
For each executed order found, create a transaction and apply to the
Portfolio.
:return:
transactions: Transaction[]
"""
transactions = list()
if self.portfolio.open_orders:
for order_id in list(self.portfolio.open_orders):
log.debug('found open order: {}'.format(order_id))
order, executed_price = self.get_order(order_id)
log.debug('got updated order {} {}'.format(
order, executed_price))
if order.status == ORDER_STATUS.FILLED:
transaction = Transaction(
asset=order.asset,
amount=order.amount,
dt=pd.Timestamp.utcnow(),
price=executed_price,
order_id=order.id,
commission=order.commission
)
transactions.append(transaction)
self.portfolio.execute_order(order, transaction)
elif order.status == ORDER_STATUS.CANCELLED:
self.portfolio.remove_order(order)
else:
delta = pd.Timestamp.utcnow() - order.dt
log.info(
'order {order_id} still open after {delta}'.format(
order_id=order_id,
delta=delta
)
)
return transactions
def get_spot_value(self, assets, field, dt=None, data_frequency='minute'):
"""
Public API method that returns a scalar value representing the value
of the desired asset's field at either the given dt.
Parameters
----------
assets : Asset, ContinuousFuture, or iterable of same.
The asset or assets whose data is desired.
field : {'open', 'high', 'low', 'close', 'volume',
'price', 'last_traded'}
The desired field of the asset.
dt : pd.Timestamp
The timestamp for the desired value.
data_frequency : str
The frequency of the data to query; i.e. whether the data is
'daily' or 'minute' bars
Returns
-------
value : float, int, or pd.Timestamp
The spot value of ``field`` for ``asset`` The return type is based
on the ``field`` requested. If the field is one of 'open', 'high',
'low', 'close', or 'price', the value will be a float. If the
``field`` is 'volume' the value will be a int. If the ``field`` is
'last_traded' the value will be a Timestamp.
Bitfinex timeframes
-------------------
Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h',
'1D', '7D', '14D', '1M'
"""
if field not in BASE_FIELDS:
raise KeyError('Invalid column: ' + str(field))
if isinstance(assets, collections.Iterable):
values = list()
for asset in assets:
value = self.get_single_spot_value(
asset, field, data_frequency)
values.append(value)
return values
else:
return self.get_single_spot_value(
assets, field, data_frequency)
def get_single_spot_value(self, asset, field, data_frequency):
"""
Similar to 'get_spot_value' but for a single asset
Note
----
We're writing each minute bar to disk using zipline's machinery.
This is especially useful when running multiple algorithms
concurrently. By using local data when possible, we try to reaching
request limits on exchanges.
:param asset:
:param field:
:param data_frequency:
:return value: The spot value of the given asset / field
"""
log.debug(
'fetching spot value {field} for symbol {symbol}'.format(
symbol=asset.symbol,
field=field
)
)
if field == 'price':
field = 'close'
# Don't use a timezone here
dt = pd.Timestamp.utcnow().floor('1 min')
value = None
if self.minute_reader is not None:
try:
# Slight delay to minimize the chances that multiple algos
# might try to hit the cache at the exact same time.
sleep_time = random.uniform(0.5, 0.8)
sleep(sleep_time)
# TODO: This does not always! Why is that? Open an issue with zipline.
# See: https://github.com/zipline-live/zipline/issues/26
value = self.minute_reader.get_value(
sid=asset.sid,
dt=dt,
field=field
)
except Exception as e:
log.warn('minute data not found: {}'.format(e))
if value is None or np.isnan(value):
ohlc = self.get_candles(data_frequency, asset)
if field not in ohlc:
raise KeyError('Invalid column: %s' % field)
if self.minute_writer is not None:
df = pd.DataFrame(
[ohlc],
index=pd.DatetimeIndex([dt]),
columns=['open', 'high', 'low', 'close', 'volume']
)
try:
self.minute_writer.write_sid(
sid=asset.sid,
df=df
)
log.debug('wrote minute data: {}'.format(dt))
except Exception as e:
log.warn(
'unable to write minute data: {} {}'.format(dt, e))
value = ohlc[field]
log.debug('got spot value: {}'.format(value))
else:
log.debug('got spot value from cache: {}'.format(value))
return value
def get_history_window(self,
assets,
end_dt,
bar_count,
frequency,
field,
data_frequency,
ffill=True):
"""
Public API method that returns a dataframe containing the requested
history window. Data is fully adjusted.
Parameters
----------
assets : list of catalyst.data.Asset objects
The assets whose data is desired.
end_dt: not applicable to cryptocurrencies
bar_count: int
The number of bars desired.
frequency: string
"1d" or "1m"
field: string
The desired field of the asset.
data_frequency: string
The frequency of the data to query; i.e. whether the data is
'daily' or 'minute' bars.
# TODO: fill how?
ffill: boolean
Forward-fill missing values. Only has effect if field
is 'price'.
Returns
-------
A dataframe containing the requested data.
"""
candles = self.get_candles(
data_frequency=frequency,
assets=assets,
bar_count=bar_count,
)
frames = []
for asset in assets:
asset_candles = candles[asset]
asset_data = dict()
asset_data[asset] = map(lambda candle: candle[field],
asset_candles)
dates = map(lambda candle: candle['last_traded'],
asset_candles)
df = pd.DataFrame(asset_data, index=dates)
frames.append(df)
return pd.concat(frames)
@abstractmethod
def order(self, asset, amount, limit_price, stop_price, style):
"""Place an order.
Parameters
----------
asset : Asset
The asset that this order is for.
amount : int
The amount of shares to order. If ``amount`` is positive, this is
the number of shares to buy or cover. If ``amount`` is negative,
this is the number of shares to sell or short.
limit_price : float, optional
The limit price for the order.
stop_price : float, optional
The stop price for the order.
style : ExecutionStyle, optional
The execution style for the order.
Returns
-------
order_id : str or None
The unique identifier for this order, or None if no order was
placed.
Notes
-----
The ``limit_price`` and ``stop_price`` arguments provide shorthands for
passing common execution styles. Passing ``limit_price=N`` is
equivalent to ``style=LimitOrder(N)``. Similarly, passing
``stop_price=M`` is equivalent to ``style=StopOrder(M)``, and passing
``limit_price=N`` and ``stop_price=M`` is equivalent to
``style=StopLimitOrder(N, M)``. It is an error to pass both a ``style``
and ``limit_price`` or ``stop_price``.
See Also
--------
:class:`catalyst.finance.execution.ExecutionStyle`
:func:`catalyst.api.order_value`
:func:`catalyst.api.order_percent`
"""
pass
@abstractmethod
def get_open_orders(self, asset):
"""Retrieve all of the current open orders.
Parameters
----------
asset : Asset
If passed and not None, return only the open orders for the given
asset instead of all open orders.
Returns
-------
open_orders : dict[list[Order]] or list[Order]
If no asset is passed this will return a dict mapping Assets
to a list containing all the open orders for the asset.
If an asset is passed then this will return a list of the open
orders for this asset.
"""
pass
@abstractmethod
def get_order(self, order_id):
"""Lookup an order based on the order id returned from one of the
order functions.
Parameters
----------
order_id : str
The unique identifier for the order.
Returns
-------
order : Order
The order object.
execution_price: float
The execution price per share of the order
"""
pass
@abstractmethod
def cancel_order(self, order_param):
"""Cancel an open order.
Parameters
----------
order_param : str or Order
The order_id or order object to cancel.
"""
pass
@abstractmethod
def get_candles(self, data_frequency, assets, bar_count=None):
"""
Retrieve OHLCV candles for the given assets
:param data_frequency:
:param assets:
:param end_dt:
:param bar_count:
:param limit:
:return:
"""
pass
@abc.abstractmethod
def tickers(self, assets):
"""
Retrieve current tick data for the given assets
:param assets:
:return:
"""
return
+60
View File
@@ -0,0 +1,60 @@
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from time import sleep
import pandas as pd
from catalyst.gens.sim_engine import (
BAR,
SESSION_START,
MINUTE_END,
SESSION_END
)
from logbook import Logger
log = Logger('ExchangeClock')
class ExchangeClock(object):
"""Realtime clock for live trading.
This class is a drop-in replacement for
:class:`zipline.gens.sim_engine.MinuteSimulationClock`.
This is a stripped down version because crypto exchanges run around the clock.
The :param:`time_skew` parameter represents the time difference between
the Broker and the live trading machine's clock.
"""
def __init__(self, sessions, time_skew=pd.Timedelta("0s")):
self.sessions = sessions
self.time_skew = time_skew
self._last_emit = None
self._before_trading_start_bar_yielded = True
def __iter__(self):
yield pd.Timestamp.utcnow(), SESSION_START
while True:
current_time = pd.Timestamp.utcnow()
current_minute = current_time.floor('1 min')
if self._last_emit is None or current_minute > self._last_emit:
log.debug('emitting minutely bar: {}'.format(current_minute))
self._last_emit = current_minute
yield current_minute, BAR
else:
sleep(1)
+60
View File
@@ -0,0 +1,60 @@
from catalyst.errors import ZiplineError
class ExchangeRequestError(ZiplineError):
msg = (
'Request failed: {error}'
).strip()
class ExchangeRequestErrorTooManyAttempts(ZiplineError):
msg = (
'Request failed: {error}, giving up after {attempts} attempts'
).strip()
class ExchangeBarDataError(ZiplineError):
msg = (
'Unable to retrieve bar data: {data_type}, ' +
'giving up after {attempts} attempts: {error}'
).strip()
class ExchangePortfolioDataError(ZiplineError):
msg = (
'Unable to retrieve portfolio data: {data_type}, ' +
'giving up after {attempts} attempts: {error}'
).strip()
class ExchangeTransactionError(ZiplineError):
msg = (
'Unable to execute transaction: {transaction_type}, ' +
'giving up after {attempts} attempts: {error}'
).strip()
class ExchangeAuthNotFound(ZiplineError):
msg = (
'Please create an auth.json file containing the api token and key for '
'exchange {exchange}. Place the file here: {filename}'
).strip()
class ExchangeSymbolsNotFound(ZiplineError):
msg = (
'Unable to download or find a local copy of symbols.json for exchange '
'{exchange}. The file should be here: {filename}'
).strip()
class AlgoPickleNotFound(ZiplineError):
msg = (
'Pickle not found for algo {algo} in path {filename}'
).strip()
class InvalidHistoryFrequencyError(ZiplineError):
msg = (
'History frequency {frequency} not supported by the exchange.'
).strip()
+87
View File
@@ -0,0 +1,87 @@
import numpy as np
from logbook import Logger
from catalyst.protocol import Portfolio, Positions, Position
log = Logger('ExchangePortfolio')
class ExchangePortfolio(Portfolio):
"""
Since the goal is to support multiple exchanges, it makes sense to
include additional stats in the portfolio object.
Instead of relying on the performance tracker, each exchange portfolio
tracks its own holding. This offers a separation between tracking an
exchange and the statistics of the algorithm.
"""
def __init__(self, start_date, starting_cash=None):
self.capital_used = 0.0
self.starting_cash = starting_cash
self.portfolio_value = starting_cash
self.pnl = 0.0
self.returns = 0.0
self.cash = starting_cash
self.positions = Positions()
self.start_date = start_date
self.positions_value = 0.0
self.open_orders = dict()
def calculate_pnl(self):
log.debug('calculating pnl')
def create_order(self, order):
log.debug('creating order {}'.format(order.id))
self.open_orders[order.id] = order
order_position = self.positions[order.asset] \
if order.asset in self.positions else None
if order_position is None:
order_position = Position(order.asset)
self.positions[order.asset] = order_position
order_position.amount += order.amount
log.debug('open order added to portfolio')
def execute_order(self, order, transaction):
log.debug('executing order {}'.format(order.id))
del self.open_orders[order.id]
order_position = self.positions[order.asset] \
if order.asset in self.positions else None
if order_position is None:
raise ValueError(
'Trying to execute order for a position not held: %s' % order.id
)
self.capital_used += order.amount * transaction.price
if order.amount > 0:
if order_position.cost_basis > 0:
order_position.cost_basis = np.average(
[order_position.cost_basis, transaction.price],
weights=[order_position.amount, order.amount]
)
else:
order_position.cost_basis = transaction.price
log.debug('updated portfolio with executed order')
def remove_order(self, order):
log.info('removing cancelled order {}'.format(order.id))
del self.open_orders[order.id]
order_position = self.positions[order.asset] \
if order.asset in self.positions else None
if order_position is None:
raise ValueError(
'Trying to remove order for a position not held: %s' % order.id
)
order_position.amount -= order.amount
log.debug('removed order from portfolio')
+133
View File
@@ -0,0 +1,133 @@
import json
import os
import pickle
import urllib
from datetime import date, datetime
from catalyst.exchange.exchange_errors import ExchangeAuthNotFound, \
ExchangeSymbolsNotFound
from catalyst.utils.paths import data_root, ensure_directory
SYMBOLS_URL = 'https://raw.githubusercontent.com/enigmampc/catalyst/' \
'live-trading/catalyst/exchange/symbols/{exchange}.json'
def get_exchange_folder(exchange_name, environ=None):
if not environ:
environ = os.environ
root = data_root(environ)
exchange_folder = os.path.join(root, 'exchanges', exchange_name)
ensure_directory(exchange_folder)
return exchange_folder
def download_exchange_symbols(exchange_name, environ=None):
exchange_folder = get_exchange_folder(exchange_name, environ)
filename = os.path.join(exchange_folder, 'symbols.json')
url = SYMBOLS_URL.format(exchange=exchange_name)
response = urllib.urlretrieve(url=url, filename=filename)
return response
def get_exchange_symbols(exchange_name, environ=None):
exchange_folder = get_exchange_folder(exchange_name, environ)
filename = os.path.join(exchange_folder, 'symbols.json')
if not os.path.isfile(filename):
download_exchange_symbols(exchange_name, environ)
if os.path.isfile(filename):
with open(filename) as data_file:
data = json.load(data_file)
return data
else:
raise ExchangeSymbolsNotFound(
exchange=exchange_name,
filename=filename
)
def get_exchange_auth(exchange_name, environ=None):
exchange_folder = get_exchange_folder(exchange_name, environ)
filename = os.path.join(exchange_folder, 'auth.json')
if os.path.isfile(filename):
with open(filename) as data_file:
data = json.load(data_file)
return data
else:
raise ExchangeAuthNotFound(
exchange=exchange_name,
filename=filename
)
def get_algo_folder(algo_name, environ=None):
if not environ:
environ = os.environ
root = data_root(environ)
algo_folder = os.path.join(root, 'live_algos', algo_name)
ensure_directory(algo_folder)
return algo_folder
def get_algo_object(algo_name, key, environ=None, rel_path=None):
folder = get_algo_folder(algo_name, environ)
if rel_path is not None:
folder = os.path.join(folder, rel_path)
filename = os.path.join(folder, key + '.p')
if os.path.isfile(filename):
try:
with open(filename, 'rb') as handle:
return pickle.load(handle)
except Exception as e:
return None
else:
return None
def save_algo_object(algo_name, key, obj, environ=None, rel_path=None):
folder = get_algo_folder(algo_name, environ)
if rel_path is not None:
folder = os.path.join(folder, rel_path)
ensure_directory(folder)
filename = os.path.join(folder, key + '.p')
with open(filename, 'wb') as handle:
pickle.dump(obj, handle, protocol=pickle.HIGHEST_PROTOCOL)
def append_algo_object(algo_name, key, obj, environ=None):
algo_folder = get_algo_folder(algo_name, environ)
filename = os.path.join(algo_folder, key + '.p')
mode = 'a+b' if os.path.isfile(filename) else 'wb'
with open(filename, mode) as handle:
pickle.dump(obj, handle, protocol=pickle.HIGHEST_PROTOCOL)
def get_exchange_minute_writer_root(exchange_name, environ=None):
exchange_folder = get_exchange_folder(exchange_name, environ)
minute_data_folder = os.path.join(exchange_folder, 'minute_data')
ensure_directory(minute_data_folder)
return minute_data_folder
def perf_serial(obj):
"""JSON serializer for objects not serializable by default json code"""
if isinstance(obj, (datetime, date)):
return obj.isoformat()
raise TypeError("Type %s not serializable" % type(obj))
+110
View File
@@ -0,0 +1,110 @@
{
"btcusd": {
"symbol": "btc_usd",
"start_date": "2010-01-01"
},
"ltcusd": {
"symbol": "ltc_usd",
"start_date": "2010-01-01"
},
"ltcbtc": {
"symbol": "ltc_btc",
"start_date": "2010-01-01"
},
"ethusd": {
"symbol": "eth_usd",
"start_date": "2010-01-01"
},
"ethbtc": {
"symbol": "eth_btc",
"start_date": "2010-01-01"
},
"etcbtc": {
"symbol": "etc_btc",
"start_date": "2010-01-01"
},
"etcusd": {
"symbol": "etc_usd",
"start_date": "2010-01-01"
},
"rrtusd": {
"symbol": "rrt_usd",
"start_date": "2010-01-01"
},
"rrtbtc": {
"symbol": "rrt_btc",
"start_date": "2010-01-01"
},
"zecusd": {
"symbol": "zec_usd",
"start_date": "2010-01-01"
},
"zecbtc": {
"symbol": "zec_btc",
"start_date": "2010-01-01"
},
"xmrusd": {
"symbol": "xmr_usd",
"start_date": "2010-01-01"
},
"xmrbtc": {
"symbol": "xmr_btc",
"start_date": "2010-01-01"
},
"dshusd": {
"symbol": "dsh_usd",
"start_date": "2010-01-01"
},
"dshbtc": {
"symbol": "dsh_btc",
"start_date": "2010-01-01"
},
"bccbtc": {
"symbol": "bcc_btc",
"start_date": "2010-01-01"
},
"bcubtc": {
"symbol": "bcu_btc",
"start_date": "2010-01-01"
},
"bccusd": {
"symbol": "bcc_usd",
"start_date": "2010-01-01"
},
"bcuusd": {
"symbol": "bcu_usd",
"start_date": "2010-01-01"
},
"xrpusd": {
"symbol": "xrp_usd",
"start_date": "2010-01-01"
},
"xrpbtc": {
"symbol": "xrp_btc",
"start_date": "2010-01-01"
},
"iotusd": {
"symbol": "iot_usd",
"start_date": "2010-01-01"
},
"iotbtc": {
"symbol": "iot_btc",
"start_date": "2010-01-01"
},
"ioteth": {
"symbol": "iot_eth",
"start_date": "2010-01-01"
},
"eosusd": {
"symbol": "eos_usd",
"start_date": "2010-01-01"
},
"eosbtc": {
"symbol": "eos_btc",
"start_date": "2010-01-01"
},
"eoseth": {
"symbol": "eos_eth",
"start_date": "2010-01-01"
}
}
+163 -42
View File
@@ -3,12 +3,18 @@ import re
from runpy import run_path
import sys
import warnings
from time import sleep
from datetime import timedelta
import pandas as pd
import click
try:
from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import TerminalFormatter
PYGMENTS = True
except:
PYGMENTS = False
@@ -29,6 +35,21 @@ from catalyst.utils.calendars import get_calendar
from catalyst.utils.factory import create_simulation_parameters
import catalyst.utils.paths as pth
from catalyst.exchange.algorithm_exchange import ExchangeTradingAlgorithm
from catalyst.exchange.data_portal_exchange import DataPortalExchange
from catalyst.exchange.bitfinex.bitfinex import Bitfinex
from catalyst.exchange.asset_finder_exchange import AssetFinderExchange
from catalyst.exchange.exchange_portfolio import ExchangePortfolio
from catalyst.exchange.exchange_errors import (
ExchangeRequestError,
ExchangeRequestErrorTooManyAttempts
)
from catalyst.exchange.exchange_utils import get_exchange_auth, \
get_algo_object
from logbook import Logger
log = Logger('run_algo')
class _RunAlgoError(click.ClickException, ValueError):
"""Signal an error that should have a different message if invoked from
@@ -68,7 +89,11 @@ def _run(handle_data,
output,
print_algo,
local_namespace,
environ):
environ,
live,
exchange,
algo_namespace,
base_currency):
"""Run a backtest for the given algorithm.
This is shared between the cli and :func:`catalyst.run_algo`.
@@ -117,6 +142,18 @@ def _run(handle_data,
else:
click.echo(algotext)
if exchange is not None:
start = pd.Timestamp.utcnow()
end = start + timedelta(minutes=1439)
open_calendar = get_calendar('OPEN')
sim_params = create_simulation_parameters(
start=start,
end=end,
capital_base=capital_base,
data_frequency=data_frequency,
emission_rate=data_frequency,
)
if bundle is not None:
bundles = bundle.split(',')
@@ -146,8 +183,6 @@ def _run(handle_data,
str(bundle_data.asset_finder.engine.url),
)
open_calendar = get_calendar('OPEN')
env = TradingEnvironment(
load=partial(load_crypto_market_data, environ=environ),
bm_symbol='USDT_BTC',
@@ -179,16 +214,16 @@ def _run(handle_data,
if b == 'poloniex':
return CryptoPricingLoader(
bundle_data,
data_frequency,
CryptoPricing,
)
bundle_data,
data_frequency,
CryptoPricing,
)
elif b == 'quandl':
return USEquityPricingLoader(
bundle_data,
data_frequency,
USEquityPricing,
)
bundle_data,
data_frequency,
USEquityPricing,
)
raise ValueError(
"No PipelineLoader registered for bundle %s." % b
)
@@ -205,20 +240,65 @@ def _run(handle_data,
)
else:
env = TradingEnvironment(environ=environ)
choose_loader = None
if live and exchange is not None:
env = TradingEnvironment(
environ=environ,
exchange_tz="UTC",
asset_db_path=None
)
env.asset_finder = AssetFinderExchange(exchange)
perf = TradingAlgorithm(
data = DataPortalExchange(
exchange=exchange,
asset_finder=env.asset_finder,
trading_calendar=open_calendar,
first_trading_day=pd.to_datetime('today', utc=True)
)
choose_loader = None
def update_portfolio(attempt_index=0):
"""
Fetch the portfolio for the exchange
We can't continue on error because it is required to bootstrap
the algorithm.
:param attempt_index:
:return:
"""
try:
exchange.update_portfolio()
return exchange.portfolio
except ExchangeRequestError as e:
if attempt_index < 20:
sleep(5)
return update_portfolio(attempt_index + 1)
else:
raise ExchangeRequestErrorTooManyAttempts(
attempts=attempt_index,
error=e
)
portfolio = update_portfolio()
sim_params = create_simulation_parameters(
start=start,
end=end,
capital_base=portfolio.starting_cash,
emission_rate='minute',
data_frequency='minute'
)
else:
env = TradingEnvironment(environ=environ)
choose_loader = None
TradingAlgorithmClass = (
partial(ExchangeTradingAlgorithm, exchange=exchange,
algo_namespace=algo_namespace)
if live and exchange else TradingAlgorithm)
perf = TradingAlgorithmClass(
namespace=namespace,
env=env,
get_pipeline_loader=choose_loader,
sim_params=create_simulation_parameters(
start=start,
end=end,
capital_base=capital_base,
data_frequency=data_frequency,
emission_rate=data_frequency,
),
sim_params=sim_params,
**{
'initialize': initialize,
'handle_data': handle_data,
@@ -294,10 +374,10 @@ def load_extensions(default, extensions, strict, environ, reload=False):
_loaded_extensions.add(ext)
def run_algorithm(start,
end,
initialize,
capital_base,
def run_algorithm(initialize,
capital_base=None,
start=None,
end=None,
handle_data=None,
before_trading_start=None,
analyze=None,
@@ -308,7 +388,11 @@ def run_algorithm(start,
default_extension=True,
extensions=(),
strict_extensions=True,
environ=os.environ):
environ=os.environ,
live=False,
exchange_name=None,
base_currency=None,
algo_namespace=None):
"""Run a trading algorithm.
Parameters
@@ -362,6 +446,12 @@ def run_algorithm(start,
environ : mapping[str -> str], optional
The os environment to use. Many extensions use this to get parameters.
This defaults to ``os.environ``.
live: execute live trading
exchange_conn: The exchange connection parameters
Supported Exchanges
-------------------
bitfinex
Returns
-------
@@ -372,26 +462,53 @@ def run_algorithm(start,
--------
catalyst.data.bundles.bundles : The available data bundles.
"""
mode = 'live' if live else 'backtest'
log.info('running algo in {mode} mode'.format(mode=mode))
load_extensions(default_extension, extensions, strict_extensions, environ)
non_none_data = valfilter(bool, {
'data': data is not None,
'bundle': bundle is not None,
})
if not non_none_data:
# if neither data nor bundle are passed use 'quantopian-quandl'
bundle = 'quantopian-quandl'
exchange = None
if mode == 'backtest':
non_none_data = valfilter(bool, {
'data': data is not None,
'bundle': bundle is not None,
})
if not non_none_data:
# if neither data nor bundle are passed use 'quantopian-quandl'
bundle = 'quantopian-quandl'
elif len(non_none_data) != 1:
raise ValueError(
'must specify one of `data`, `data_portal`, or `bundle`,'
' got: %r' % non_none_data,
)
elif len(non_none_data) != 1:
raise ValueError(
'must specify one of `data`, `data_portal`, or `bundle`,'
' got: %r' % non_none_data,
)
elif 'bundle' not in non_none_data and bundle_timestamp is not None:
raise ValueError(
'cannot specify `bundle_timestamp` without passing `bundle`',
)
elif 'bundle' not in non_none_data and bundle_timestamp is not None:
raise ValueError(
'cannot specify `bundle_timestamp` without passing `bundle`',
)
else:
if exchange_name is not None:
portfolio = get_algo_object(
algo_name=algo_namespace,
key='portfolio_{}'.format(exchange_name),
environ=environ
)
if portfolio is None:
portfolio = ExchangePortfolio(
start_date=pd.Timestamp.utcnow()
)
exchange_auth = get_exchange_auth(exchange_name)
if exchange_name == 'bitfinex':
exchange = Bitfinex(
key=exchange_auth['key'],
secret=exchange_auth['secret'].encode('UTF-8'),
base_currency=base_currency,
portfolio=portfolio
)
else:
raise NotImplementedError(
'exchange not supported: %s' % exchange_name)
return _run(
handle_data=handle_data,
@@ -412,4 +529,8 @@ def run_algorithm(start,
print_algo=False,
local_namespace=False,
environ=environ,
live=live,
exchange=exchange,
algo_namespace=algo_namespace,
base_currency=base_currency
)
+207
View File
@@ -0,0 +1,207 @@
<h1>Live Trading Blueprint</h1>
The purpose of this document is to allow project contributors navigate
through the ongoing live trading implementation.
<h2>Components</h2>
At a high level, the following components have been implemented to coerce
zipline into live trading.
<h3>Exchange</h3>
*catalyst/exchange*
Exchange is a new package introducing cryptocurrency
exchanges to zipline. The package contains mostly new implementations
of existing components, adapted to characteristics of exchanges.
Here are some key characteristics which make cryptocurrency exchanges
exchanges different compared to equity brokers.
* They trade around the clock.
* Currency symbols are inconsistent across exchanges.
* They trade currency pairs (i.e. the base currency is not always be USD).
This is a paradigm shift in context of zipline. Additional
business logic will be required to manage the portfolio data and orders.
* The price of a single asset might vary across exchanges. This means
arbitrage opportunities. Consequently, to extract maximum alpha, the
platform should not only support multiple exchanges, but also multiple
exchanges per algorithm.
* The fee model is usually more complex than that of an equity broker.
It can vary drastically between exchanges.
* There are no splits, mergers, etc. to worry about.
* A complete order book is usually available, the platform should
offer access to it order to help traders reduce slippage.
<h3>New Components</h3>
These components of the exchange package were added to the zipline
sources.
<h4>Exchange</h4>
*catalyst/exchange/exchange.py*
Abstract class which acts as an interface for the implementation of
various exchanges. It also contains logic common to all exchanges.
<h4>Bitfinex</h4>
*catalyst/exchange/bitfinex.py*
The Bitfinex exchange implementation. It extends the Exchange class.
<h4>DataPortalExchange</h4>
*catalyst/exchange/data_portal_exchange.py*
Extends the zipline DataPortal to route spot data to the exchange.
This is critical because it allows the algoritm to request data in
real-time.
For example, `data.current(asset, 'price')` retrieves the current price
of the asset, not the price at the time of yielding the bar this
is critical to minimize slippage.
At the time of writing, it only supports spot data but I believe that
it should be extended to historical data as well. Some exchanges
have better historical data APIs than others. This will need to
be considered during each individual implementation.
<h4>ExchangeClock</h4>
*catalyst/exchange/exchange_clock.py*
An implementation to the zipline Clock which runs 24/7. It yields a
bar every minute.
<h4>AssetFinderExchange</h4>
*catalyst/exchange/asset_finder_exchange.py*
An alternate implementation of AssetFinder which locates each asset
against the exchanges instead of bundle databases.
For example, `symbol('eth_usd')` should return an Ethereum/USD asset
regardless of currency notation of the target exchange.
To acheive this, I have created a dictionary of currencies for the
Bitfinex exchange. Here is what it looks like.
* Each key represents the exchange specific symbol.
* The symbol attribute represents the abstract symbol common across
all exchanges for the given currency.
* The start_date attribute should correspond to its first trading day
on the exchange.
```json
{
"btcusd": {
"symbol": "btc_usd",
"start_date": "2010-01-01"
},
"ltcusd": {
"symbol": "ltc_usd",
"start_date": "2010-01-01"
},
"ltcbtc": {
"symbol": "ltc_btc",
"start_date": "2010-01-01"
},
"ethusd": {
"symbol": "eth_usd",
"start_date": "2010-01-01"
},
"ethbtc": {
"symbol": "eth_btc",
"start_date": "2010-01-01"
}
}
```
<h4>ExchangeTradingAlgorithm</h4>
*catalyst/exchange/algorithm_exchange.py*
Extends the TradingAlgorithm class which orchestrates the api
operations. This class brings together most of the components
described above.
<h3>Modified Components</h3>
The following components have been modified to include conditional
business logic to enable live trading.
<h4>run_algorithm</h4>
*catalyst/utils/run_algo.py*
The run_algorithm interface is an entry point to execute an
algorithm in zipline. This component was already modified for
the catalyst concurrency bundles. I added conditional logic
which should not interfere with backtesting.
In a nutshell, the run_algorithm method now contains three additional
parameters:
* live: If True, zipline will attempt to trade live. If False or not
specified, it will run a backtest as normal.
* algo_namespace: An arbitrary namespace for the current algorithm.
It will be used to persist data between runs.
* exchange_conn: A dictionary containing the attributes required
to instantiate an exchange. Here is an example for Bitfinex:
```python
exchange_conn = dict(
name='bitfinex',
key='',
secret=b'',
base_currency='usd'
)
```
The following sample algorithm uses the run_algorithm interface:
*catalyst/examples/buy_and_hold_live.py*
<h2>Portfolio Management</h2>
Zipline has a Portfolio class containing key metrics used by zipline
for, but not only, these reasons:
* Placing orders: When placing orders (e.g. order_target_percent),
zipline queries the portfolio to assess the size of current positions,
cash available, etc.
* Measuring performance: The portfolio contains attributes like
cost basis of each asset, p&l, etc. which zipline uses to compute all
of its performance criteria.
When backtesting, zipline automatically updates the Portfolio object
of its corresponding algorithm. When live trading, these updates should
be the responsibility of the exchange as it holds the truth for:
* Executed price of each order (including fees and slippage)
* Partial / failed orders
* Cash (i.e. base currency) available
* Cost basis of each position
If each exchange account had a one-to-one relationship with an
algorithm, portfolio metrics could be retrieved directly from the
exchange without persisting any data to the algorithm. However,
doing this would have at least the following drawbacks:
* It may not be reasonable to ask users to dedicate an
exchange account to a single algorithm. Exchanges are not easy
to partition.
* If an exchange account contains existing positions, the calculated
cost basis would correspond to all positions, not just those
initiated by the algorithm.
* It would not be possible impose trading limits on algorithms.
It follows that Portfolio metrics should be calculated using a strategic
combination of the exchange data and algorithm activity. While tracking
the activity of an algorithm works well in backtesting, it is more
challenging during live trading. A live algorithm might run over
several months. It might have to stop and start for many reasons.
This means that the platform should have the ability to persist
algorithm activity in order to be reliable.
In the interest of time, I will start by persisting algorithm
activity in memory. Data will be lost when the algorithm execution stops.
The intent it to offer a simple basis from which to implement data
persistence strategies in the future.
View File
+46
View File
@@ -0,0 +1,46 @@
import unittest
from abc import ABCMeta, abstractmethod
class BaseExchangeTestCase():
__metaclass__ = ABCMeta
@abstractmethod
def test_positions(self):
pass
@abstractmethod
def test_portfolio(self):
pass
@abstractmethod
def test_account(self):
pass
@abstractmethod
def test_time_skew(self):
pass
@abstractmethod
def test_get_open_orders(self):
pass
@abstractmethod
def test_order(self):
pass
@abstractmethod
def test_get_order(self):
pass
@abstractmethod
def test_cancel_order(self):
pass
@abstractmethod
def test_get_spot_value(self):
pass
@abstractmethod
def test_tickers(self):
pass
+94
View File
@@ -0,0 +1,94 @@
from catalyst.exchange.bitfinex import Bitfinex
from .base import BaseExchangeTestCase
from logbook import Logger
import pandas as pd
from catalyst.finance.execution import (MarketOrder,
LimitOrder,
StopOrder,
StopLimitOrder)
log = Logger('BitfinexTestCase')
class BitfinexTestCase(BaseExchangeTestCase):
def test_positions(self):
log.info('querying positions from bitfinex')
bitfinex = Bitfinex()
balance = bitfinex.positions()
log.info('the balance: {}'.format(balance))
pass
def test_portfolio(self):
log.info('fetching portfolio data')
pass
def test_account(self):
log.info('fetching account data')
pass
def test_time_skew(self):
log.info('time skew not implemented')
pass
def test_get_open_orders(self):
log.info('fetching open orders')
bitfinex = Bitfinex()
order_id = bitfinex.get_open_orders()
log.info('open orders: {}'.format(order_id))
pass
def test_order(self):
log.info('ordering from bitfinex')
bitfinex = Bitfinex()
order_id = bitfinex.order(
asset=bitfinex.get_asset('eth_usd'),
style=LimitOrder(limit_price=200),
limit_price=200,
amount=0.5,
stop_price=None
)
log.info('order created {}'.format(order_id))
pass
def test_get_order(self):
log.info('querying orders from bitfinex')
bitfinex = Bitfinex()
response = bitfinex.get_order(order_id=3361248395)
log.info('the order: {}'.format(response))
pass
def test_cancel_order(self):
log.info('canceling order from bitfinex')
bitfinex = Bitfinex()
response = bitfinex.cancel_order(order_id=3330847408)
log.info('canceled order: {}'.format(response))
pass
def test_get_spot_value(self):
log.info('spot value not implemented')
bitfinex = Bitfinex()
assets = [
bitfinex.get_asset('eth_usd'),
bitfinex.get_asset('etc_usd'),
bitfinex.get_asset('eos_usd'),
]
# assets = bitfinex.get_asset('eth_usd')
value = bitfinex.get_spot_value(
assets=assets,
field='close',
data_frequency='minute'
)
pass
def test_tickers(self):
log.info('fetching ticker from bitfinex')
bitfinex = Bitfinex()
current_date = pd.Timestamp.utcnow()
assets = [
bitfinex.get_asset('eth_usd'),
bitfinex.get_asset('etc_usd'),
bitfinex.get_asset('eos_usd'),
]
tickers = bitfinex.tickers(date=current_date, assets=assets)
log.info('got tickers {}'.format(tickers))
pass
+50
View File
@@ -0,0 +1,50 @@
from unittest import TestCase
from logbook import Logger
from mock import patch, sentinel
from catalyst.exchange.exchange_clock import ExchangeClock
from catalyst.utils.calendars.trading_calendar import days_at_time
from datetime import time
from collections import defaultdict
from catalyst.utils.calendars import get_calendar
import pandas as pd
log = Logger('ExchangeClockTestCase')
class ExchangeClockTestCase(TestCase):
@classmethod
def setUpClass(cls):
cls.open_calendar = get_calendar("OPEN")
cls.sessions = pd.Timestamp.utcnow()
def setUp(self):
self.internal_clock = None
self.events = defaultdict(list)
def advance_clock(self, x):
"""Mock function for sleep. Advances the internal clock by 1 min"""
# The internal clock advance time must be 1 minute to match
# MinutesSimulationClock's update frequency
self.internal_clock += pd.Timedelta('1 min')
def get_clock(self, arg, *args, **kwargs):
"""Mock function for pandas.to_datetime which is used to query the
current time in RealtimeClock"""
assert arg == "now"
return self.internal_clock
def test_clock(self):
with patch('catalyst.exchange.exchange_clock.pd.to_datetime') as to_dt, \
patch('catalyst.exchange.exchange_clock.sleep') as sleep:
clock = ExchangeClock(sessions=self.sessions)
to_dt.side_effect = self.get_clock
sleep.side_effect = self.advance_clock
start_time = pd.Timestamp.utcnow()
self.internal_clock = start_time
events = list(clock)
# Event 0 is SESSION_START which always happens at 00:00.
ts, event_type = events[1]
pass