{"action":"created","issue":{"url":"https://api.github.com/repos/quantopian/empyrical/issues/47","repository_url":"https://api.github.com/repos/quantopian/empyrical","labels_url":"https://api.github.com/repos/quantopian/empyrical/issues/47/labels{/name}","comments_url":"https://api.github.com/repos/quantopian/empyrical/issues/47/comments","events_url":"https://api.github.com/repos/quantopian/empyrical/issues/47/events","html_url":"https://github.com/quantopian/empyrical/pull/47","id":229985834,"number":47,"title":"Additional Calculations & Roll, Up, Down Helpers","user":{"login":"cgdeboer","id":174766,"avatar_url":"https://avatars2.githubusercontent.com/u/174766?v=3","gravatar_id":"","url":"https://api.github.com/users/cgdeboer","html_url":"https://github.com/cgdeboer","followers_url":"https://api.github.com/users/cgdeboer/followers","following_url":"https://api.github.com/users/cgdeboer/following{/other_user}","gists_url":"https://api.github.com/users/cgdeboer/gists{/gist_id}","starred_url":"https://api.github.com/users/cgdeboer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cgdeboer/subscriptions","organizations_url":"https://api.github.com/users/cgdeboer/orgs","repos_url":"https://api.github.com/users/cgdeboer/repos","events_url":"https://api.github.com/users/cgdeboer/events{/privacy}","received_events_url":"https://api.github.com/users/cgdeboer/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":16,"created_at":"2017-05-19T14:06:58Z","updated_at":"2017-06-12T16:05:53Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/quantopian/empyrical/pulls/47","html_url":"https://github.com/quantopian/empyrical/pull/47","diff_url":"https://github.com/quantopian/empyrical/pull/47.diff","patch_url":"https://github.com/quantopian/empyrical/pull/47.patch"},"body":"## Summary\r\nAdded a few helper methods in the utils file that allow us to stack some transformation logic together before calling an actual metric. For example, if we want to calculate the rolling up capture of a strategy vs its benchmark, we want to be able to do something like `[roll,up, capture]` where `roll`, `up`, `capture`, are each methods that perform either a series deconstruction (roll), a filter (up), or a calculation (capture). Doing it this why is more DRY than embedding roll and filter logic in each method, but does add some complication. \r\n\r\nI elected to add a variety of small methods to the `stats` file that wrap the complexity described above. This way we keep the API the user is used to calling the same. e.g there is actually a method called `rolling_up_capture` that takes the expected \"returns, factor_returns\" arguments. That function simply calls the more complex stacked function to get the results.\r\n\r\n## Details\r\n- added new methods details below.\r\n- added roll, up, and down as stackable methods to use in future calculations\r\n- added a handful of tests for new methods\r\n- corrected an issue with the `max_drawdown`. See note below\r\n- updated `nose_parameterized` to just `parameterized`\r\n- move date/period symbols into a separate file\r\n- added some examples to the README\r\n\r\n## Not Done\r\n- add `information_ratio` per #41 \r\n- bump `empyrical` version\r\n- add remainder of tests.\r\n\r\n#### Max Drawdown\r\nThe `max_drawdown` code was not considering the first return in the array. The `max_return` array did not consider the starting value of 100 used in the function. In cases where ALL the returns in the array are negative, the max value in the array will be the 100 * (1+ the first negative return). For e.g if the first return in the array is `-0.02`, then the max value in the array will be 98. This will cause max drawdowns to appear less severe than if they started at 100. \r\n\r\nThe max drawdown code was masquerading as correct because the `negative_returns` Series in the test suite starts with a 0. (i.e they aren't all negative). \r\n\r\nI've corrected that by ensuring that the `cum_returns` array starts with a value that matches the base value.\r\n\r\n#### New Methods\r\n```\r\n    capture,\r\n    up_capture,\r\n    down_capture,\r\n    up_down_capture,\r\n    up_alpha_beta,\r\n    down_alpha_beta,\r\n    roll_max_drawdown,\r\n    roll_up_capture,\r\n    roll_down_capture,\r\n    roll_up_down_capture,\r\n    roll_alpha_beta,\r\n    roll_sharpe_ratio,\r\n```\r\n\r\nResolves #41 #46 "},"comment":{"url":"https://api.github.com/repos/quantopian/empyrical/issues/comments/307836274","html_url":"https://github.com/quantopian/empyrical/pull/47#issuecomment-307836274","issue_url":"https://api.github.com/repos/quantopian/empyrical/issues/47","id":307836274,"user":{"login":"cgdeboer","id":174766,"avatar_url":"https://avatars2.githubusercontent.com/u/174766?v=3","gravatar_id":"","url":"https://api.github.com/users/cgdeboer","html_url":"https://github.com/cgdeboer","followers_url":"https://api.github.com/users/cgdeboer/followers","following_url":"https://api.github.com/users/cgdeboer/following{/other_user}","gists_url":"https://api.github.com/users/cgdeboer/gists{/gist_id}","starred_url":"https://api.github.com/users/cgdeboer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cgdeboer/subscriptions","organizations_url":"https://api.github.com/users/cgdeboer/orgs","repos_url":"https://api.github.com/users/cgdeboer/repos","events_url":"https://api.github.com/users/cgdeboer/events{/privacy}","received_events_url":"https://api.github.com/users/cgdeboer/received_events","type":"User","site_admin":false},"created_at":"2017-06-12T16:05:53Z","updated_at":"2017-06-12T16:05:53Z","body":"Most of the new tests are now written, just taking some extra time to double check the inputs vs expected."}}
{"actor":{"display_login":"cgdeboer"}}