@@ -24,7 +24,7 @@ def compound_arithmetic(returns: pd.Series) -> float:
2424 """Performs arithmatic compounding.
2525
2626 e.g. if there are 3 returns r1, r2, r3,
27- calculate `` r1 + r2`` + r3
27+ calculate r1 + r2 + r3
2828
2929 Args:
3030 returns: pandas series of returns, in decimals.
@@ -41,7 +41,7 @@ def compound_continuous(returns: pd.Series) -> float:
4141 """Performs continuous compounding.
4242
4343 e.g. if there are 3 returns r1, r2, r3,
44- calculate exp(`` r1 + r2`` + r3) - 1
44+ calculate exp(r1 + r2 + r3) - 1
4545
4646 Args:
4747 returns: pandas series of returns, in decimals.
@@ -60,9 +60,9 @@ def compound(method: str) -> Callable:
6060 Args:
6161 method: method of compounding in the generated function
6262
63- * 'geometric': geometric compounding ``(1+r1) * (1+r2) - 1``
64- * 'arithmetic': arithmetic compounding ``r1 + r2``
65- * 'continuous': continous compounding ``exp(r1+r2) - 1``
63+ * 'geometric': geometric compounding ``(1+r1) * (1+r2) - 1``
64+ * 'arithmetic': arithmetic compounding ``r1 + r2``
65+ * 'continuous': continous compounding ``exp(r1+r2) - 1``
6666
6767 Raises:
6868 ValueError: when method is not supported.
@@ -86,6 +86,99 @@ def compound(method: str) -> Callable:
8686 return compound [method ]
8787
8888
89+ def cumseries_geometric (returns : pd .Series ) -> pd .Series :
90+ """Performs geometric compounding to create cumulative index series.
91+
92+ e.g. if there are 3 returns r1, r2, r3,
93+ calculate
94+ (1+r1) - 1,
95+ (1+r1) * (1+r2) - 1,
96+ (1+r1) * (1+r2) * (1+r3) - 1
97+
98+ Args:
99+ returns: pandas series of returns, in decimals.
100+ i.e. 3% should be expressed as 0.03, not 3.
101+
102+ Returns:
103+ returns: pandas series of cumulative index, in decimals.
104+ """
105+
106+ return (1 + returns ).cumprod () - 1
107+
108+
109+ def cumseries_arithmetic (returns : pd .Series ) -> pd .Series :
110+ """Performs arithmatic compounding to create cumulative index series.
111+
112+ e.g. if there are 3 returns r1, r2, r3,
113+ calculate
114+ r1
115+ r1 + r2
116+ r1 + r2 + r3
117+
118+ Args:
119+ returns: pandas series of returns, in decimals.
120+ i.e. 3% should be expressed as 0.03, not 3.
121+
122+ Returns:
123+ returns: pandas series of cumulative index, in decimals.
124+ """
125+
126+ return returns .cumsum ()
127+
128+
129+ def cumseries_continuous (returns : pd .Series ) -> float :
130+ """Performs continuous compounding to create cumulative index series.
131+
132+ e.g. if there are 3 returns r1, r2, r3,
133+ calculate
134+ exp(r1) - 1
135+ exp(r1 + r2) - 1
136+ exp(r1 + r2 + r3) - 1
137+
138+ Args:
139+ returns: pandas series of returns, in decimals.
140+ i.e. 3% should be expressed as 0.03, not 3.
141+
142+ Returns:
143+ returns: pandas series of cumulative index, in decimals.
144+ """
145+
146+ return returns .cumsum ().apply (lambda x : math .exp (x ) - 1 )
147+
148+
149+ def cumseries (method : str ) -> Callable :
150+ """Factory for producing compound functions.
151+
152+ Args:
153+ method: method of compounding in the generated function
154+
155+ * 'geometric': geometric compounding
156+ * 'arithmetic': arithmetic compounding
157+ * 'continuous': continous compounding
158+
159+ Raises:
160+ ValueError: when method is not supported.
161+
162+ Returns:
163+ Callable: a function that takes a pandas series as its argument, and
164+ compound it to create a cumulative index sereis according to the
165+ method specified.
166+ """
167+
168+ if method not in ["arithmetic" , "geometric" , "continuous" ]:
169+ raise ValueError (
170+ "Method should be one of 'geometric', 'arithmetic' or 'continuous'"
171+ )
172+
173+ cumseries = {
174+ "arithmetic" : cumseries_arithmetic ,
175+ "geometric" : cumseries_geometric ,
176+ "continuous" : cumseries_continuous ,
177+ }
178+
179+ return cumseries [method ]
180+
181+
89182def ret_to_period (df : pd .DataFrame , freq : str , method : str ):
90183 """Converts return series to a different (and lower) frequency.
91184
0 commit comments