Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support pandas>=0.18.1 #443

Merged
merged 4 commits into from
Oct 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
language: python
sudo: false

python:
- "2.7"
- "3.5"
- "3.6"
python:
- 2.7
- 3.5
- 3.6

env:
- PANDAS_VERSION=0.18.1
- PANDAS_VERSION=0.19.2
- PANDAS_VERSION=0.20.3

matrix:
exclude:
- python: 3.6
env: PANDAS_VERSION=0.18.1

before_install:
# We do this conditionally because it saves us some downloading if the
Expand All @@ -24,7 +34,7 @@ before_install:
- cp pyfolio/tests/matplotlibrc .

install:
- conda create -q -n testenv --yes python=$TRAVIS_PYTHON_VERSION ipython pyzmq numpy scipy nose matplotlib pandas Cython patsy flake8 seaborn scikit-learn runipy pytables networkx pandas-datareader matplotlib-tests joblib
- conda create -q -n testenv --yes python=$TRAVIS_PYTHON_VERSION ipython pyzmq numpy scipy nose matplotlib pandas=$PANDAS_VERSION Cython patsy flake8 seaborn scikit-learn runipy pytables networkx pandas-datareader matplotlib-tests joblib
- source activate testenv
- pip install nose_parameterized
#- pip install --no-deps git+https://github.com/quantopian/zipline
Expand Down
4 changes: 4 additions & 0 deletions pyfolio/pos.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ def extract_pos(positions, cash):

values = values.join(cash).fillna(0)

# NOTE: Set name of DataFrame.columns to sid, to match the behavior
# of DataFrame.join in earlier versions of pandas.
values.columns.name = 'sid'

return values


Expand Down
34 changes: 27 additions & 7 deletions pyfolio/risk.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
# 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 numpy as np
import matplotlib.pyplot as plt
from collections import OrderedDict
from functools import partial

import matplotlib.pyplot as plt
import numpy as np


SECTORS = OrderedDict([
(101, 'Basic Materials'),
Expand Down Expand Up @@ -432,9 +435,26 @@ def compute_volume_exposures(shares_held, volumes, percentile):
shorted_frac = shares_shorted.divide(volumes)
grossed_frac = shares_grossed.divide(volumes)

longed_threshold = 100*longed_frac.quantile(percentile, axis='columns')
shorted_threshold = 100*shorted_frac.quantile(percentile, axis='columns')
grossed_threshold = 100*grossed_frac.quantile(percentile, axis='columns')
# NOTE: To work around a bug in `quantile` with nan-handling in
# pandas 0.18, use np.nanpercentile by applying to each row of
# the dataframe. This is fixed in pandas 0.19.
#
# longed_threshold = 100*longed_frac.quantile(percentile, axis='columns')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cruft?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just leaving these as a reference for when we no longer need to support 0.18, does that sound alright?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup sounds good

# shorted_threshold = 100*shorted_frac.quantile(percentile, axis='columns')
# grossed_threshold = 100*grossed_frac.quantile(percentile, axis='columns')

longed_threshold = 100 * longed_frac.apply(
partial(np.nanpercentile, q=100 * percentile),
axis='columns',
)
shorted_threshold = 100 * shorted_frac.apply(
partial(np.nanpercentile, q=100 * percentile),
axis='columns',
)
grossed_threshold = 100 * grossed_frac.apply(
partial(np.nanpercentile, q=100 * percentile),
axis='columns',
)

return longed_threshold, shorted_threshold, grossed_threshold

Expand Down Expand Up @@ -465,7 +485,7 @@ def plot_volume_exposures_longshort(longed_threshold, shorted_threshold,
ax.axhline(0, color='k')
ax.set(title='Long and short exposures to illiquidity',
ylabel='{}th percentile of proportion of volume (%)'
.format(100*percentile))
.format(100 * percentile))
ax.legend(frameon=True, framealpha=0.5)

return ax
Expand Down Expand Up @@ -494,7 +514,7 @@ def plot_volume_exposures_gross(grossed_threshold, percentile, ax=None):
ax.axhline(0, color='k')
ax.set(title='Gross exposure to illiquidity',
ylabel='{}th percentile of \n proportion of volume (%)'
.format(100*percentile))
.format(100 * percentile))
ax.legend(frameon=True, framealpha=0.5)

return ax
4 changes: 2 additions & 2 deletions pyfolio/round_trips.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def vwap(transaction):
t['order_sign'] = t.amount > 0
t['block_dir'] = (t.order_sign.shift(
1) != t.order_sign).astype(int).cumsum()
t['block_time'] = ((t.dt - t.dt.shift(1)) >
t['block_time'] = ((t.dt.sub(t.dt.shift(1))) >
max_delta).astype(int).cumsum()
grouped_price = (t.groupby(('block_dir',
'block_time'))
Expand Down Expand Up @@ -252,7 +252,7 @@ def extract_round_trips(transactions,

roundtrips = pd.DataFrame(roundtrips)

roundtrips['duration'] = roundtrips['close_dt'] - roundtrips['open_dt']
roundtrips['duration'] = roundtrips['close_dt'].sub(roundtrips['open_dt'])

if portfolio_value is not None:
# Need to normalize so that we can join
Expand Down
1 change: 1 addition & 0 deletions pyfolio/tests/test_pos.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def test_extract_pos(self):
index=index
)
expected.index.name = 'index'
expected.columns.name = 'sid'

assert_frame_equal(result, expected)

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
'ipython>=3.2.3' if support_ipython_6 else 'ipython>=3.2.3, <6',
'matplotlib>=1.4.0',
'numpy>=1.9.1',
'pandas>=0.19.0',
'pandas>=0.18.1',
'pytz>=2014.10',
'scipy>=0.14.0',
'scikit-learn>=0.18.2',
Expand Down