Skip to content

Commit 1e4d5af

Browse files
Fix return calculations for pandas 0.23.*
There was a bug introduced in pandas 0.23.* using pct_change() on a groupby. Details at pandas-dev/pandas#21200
1 parent da53d3f commit 1e4d5af

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

strategy/strategy.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@
1818
WARNINGS = "default"
1919

2020

21+
# non vectorized, related to
22+
# https://github.com/pandas-dev/pandas/issues/21200
23+
if pd.__version__.startswith("0.23."):
24+
def calc_returns(s):
25+
return s.groupby(level=1).apply(lambda x: x.pct_change())
26+
else:
27+
def calc_returns(s):
28+
return s.groupby(level=1).pct_change()
29+
30+
2131
class Exposures():
2232
"""
2333
A data container for market data on equities and futures instruments.
@@ -752,8 +762,7 @@ def continuous_rets(self):
752762

753763
irets = {}
754764
for ast in self._exposures.root_futures:
755-
irets[ast] = (self._exposures.prices[ast].settle
756-
.groupby(level=1).pct_change())
765+
irets[ast] = calc_returns(self._exposures.prices[ast].settle)
757766

758767
if irets:
759768
weights = self.instrument_weights()

tests/test_strategy.py

+12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from strategy.strategy import Exposures
33
import strategy.strategy as strat
44
import pandas as pd
5+
import numpy as np
56
import unittest
67
from collections import namedtuple
78
import os
@@ -350,3 +351,14 @@ def test_simulation_fungible_reinvest_futures(self):
350351

351352
exp_sim_res = self.make_container(hlds_exp, trds_exp, pnls_exp)
352353
self.assert_simulation_equal(sim_res, exp_sim_res)
354+
355+
def test_return_calculations(self):
356+
# https://github.com/pandas-dev/pandas/issues/21200
357+
idx = pd.MultiIndex.from_product(
358+
[pd.date_range("2015-01-01", "2015-01-03"), ["A1", "A2"]]
359+
)
360+
s = pd.Series([1, 3, 1.5, 1.5, 3, 4.5], index=idx)
361+
362+
rets = strat.calc_returns(s)
363+
rets_exp = pd.Series([np.NaN, np.NaN, 0.5, -0.5, 1, 2], index=idx)
364+
assert_series_equal(rets, rets_exp)

0 commit comments

Comments
 (0)