0
# Performance Analysis
1
2
Comprehensive performance evaluation with detailed statistics, risk metrics, and visualization capabilities. Provides both single-asset analysis through PerformanceStats and multi-asset comparative analysis through GroupStats.
3
4
## Capabilities
5
6
### PerformanceStats Class
7
8
Performance evaluation class for individual price series containing comprehensive statistics, visualizations, and derived metrics.
9
10
```python { .api }
11
class PerformanceStats:
12
def __init__(self, prices, rf=0.0, annualization_factor=None):
13
"""
14
Initialize performance statistics for a price series.
15
16
Parameters:
17
- prices (pd.Series): Price series with datetime index
18
- rf (float, pd.Series): Risk-free rate (annualized) or risk-free rate price series
19
- annualization_factor (float): Annualization factor (default: 252)
20
"""
21
22
def set_riskfree_rate(self, rf):
23
"""
24
Set annual risk-free rate and recalculate statistics.
25
26
Parameters:
27
- rf (float): Annual risk-free rate
28
"""
29
30
def set_date_range(self, start, end):
31
"""
32
Update date range for analysis and recalculate statistics.
33
34
Parameters:
35
- start: Start date
36
- end: End date
37
"""
38
39
def display(self):
40
"""Display comprehensive statistics overview."""
41
42
def display_monthly_returns(self):
43
"""Display monthly returns table with YTD figures."""
44
45
def display_lookback_returns(self):
46
"""Display current lookback returns for various periods."""
47
48
def plot(self, freq='D', figsize=None, title=None, logy=False, **kwargs):
49
"""
50
Plot price series.
51
52
Parameters:
53
- freq (str): Frequency for resampling ('D', 'M', 'Y')
54
- figsize (tuple): Figure size
55
- title (str): Plot title
56
- logy (bool): Use logarithmic y-axis
57
- **kwargs: Additional matplotlib arguments
58
"""
59
60
def plot_histogram(self, freq='D', figsize=None, title=None, bins=50, **kwargs):
61
"""
62
Plot return distribution histogram.
63
64
Parameters:
65
- freq (str): Frequency for resampling
66
- figsize (tuple): Figure size
67
- title (str): Plot title
68
- bins (int): Number of histogram bins
69
- **kwargs: Additional matplotlib arguments
70
"""
71
72
def to_csv(self, sep=',', path=None):
73
"""
74
Export statistics to CSV format.
75
76
Parameters:
77
- sep (str): Column separator
78
- path (str): File path (if None, returns string)
79
"""
80
```
81
82
**Core Properties:**
83
- `name` (str): Series name derived from input
84
- `prices` (Series): Original price series
85
- `rf` (float/Series): Risk-free rate used in calculations
86
- `annualization_factor` (float): Trading days per year (default: 252)
87
- `start`, `end` (datetime): Analysis period start and end dates
88
89
**Price and Return Series:**
90
- `daily_prices`, `monthly_prices`, `yearly_prices` (Series): Resampled price series
91
- `returns`, `log_returns` (Series): Daily return series (simple and log)
92
- `monthly_returns`, `yearly_returns` (Series): Monthly and yearly return series
93
94
**Return Performance Metrics:**
95
- `total_return` (float): Total return over entire period
96
- `cagr` (float): Compound Annual Growth Rate
97
- `incep` (float): Since inception return (same as CAGR)
98
99
**Lookback Period Returns:**
100
- `mtd`, `three_month`, `six_month` (float): Short-term returns
101
- `ytd`, `one_year` (float): Medium-term returns
102
- `three_year`, `five_year`, `ten_year` (float): Long-term annualized returns
103
104
**Risk and Drawdown Analysis:**
105
- `max_drawdown` (float): Maximum drawdown
106
- `drawdown` (Series): Complete drawdown series
107
- `drawdown_details` (DataFrame): Detailed drawdown analysis (Start, End, Length, drawdown)
108
- `avg_drawdown`, `avg_drawdown_days` (float): Average drawdown and duration
109
110
**Daily Statistics:**
111
- `daily_mean`, `daily_vol` (float): Daily mean and volatility (annualized)
112
- `daily_sharpe`, `daily_sortino` (float): Daily Sharpe and Sortino ratios
113
- `daily_skew`, `daily_kurt` (float): Daily returns skewness and kurtosis
114
- `best_day`, `worst_day` (float): Best and worst single day returns
115
116
**Monthly Statistics:**
117
- `monthly_mean`, `monthly_vol` (float): Monthly mean and volatility (annualized)
118
- `monthly_sharpe`, `monthly_sortino` (float): Monthly Sharpe and Sortino ratios
119
- `monthly_skew`, `monthly_kurt` (float): Monthly returns skewness and kurtosis
120
- `best_month`, `worst_month` (float): Best and worst single month returns
121
- `pos_month_perc` (float): Percentage of positive months
122
- `avg_up_month`, `avg_down_month` (float): Average positive/negative month returns
123
124
**Yearly Statistics:**
125
- `yearly_mean`, `yearly_vol` (float): Yearly mean and volatility
126
- `yearly_sharpe`, `yearly_sortino` (float): Yearly Sharpe and Sortino ratios
127
- `yearly_skew`, `yearly_kurt` (float): Yearly returns skewness and kurtosis
128
- `best_year`, `worst_year` (float): Best and worst single year returns
129
- `win_year_perc`, `twelve_month_win_perc` (float): Winning year percentages
130
131
**Composite Risk Metrics:**
132
- `calmar` (float): Calmar ratio (CAGR / |Max Drawdown|)
133
134
**Structured Data Properties:**
135
- `stats` (Series): All key statistics in one Series with labeled index
136
- `return_table` (DataFrame): Monthly returns table (years × months + YTD column)
137
- `lookback_returns` (Series): Returns for different periods ['mtd', '3m', '6m', 'ytd', '1y', '3y', '5y', '10y', 'incep']
138
139
### GroupStats Class
140
141
Comparative analysis class for multiple price series providing side-by-side statistics and visualization capabilities.
142
143
```python { .api }
144
class GroupStats:
145
def __init__(self, *prices):
146
"""
147
Initialize comparative statistics for multiple price series.
148
149
Parameters:
150
- *prices: Multiple price series (pd.Series) to compare
151
"""
152
153
def set_riskfree_rate(self, rf):
154
"""
155
Set risk-free rate for all series and recalculate statistics.
156
157
Parameters:
158
- rf (float): Annual risk-free rate
159
"""
160
161
def set_date_range(self, start, end):
162
"""
163
Update date range for all series and recalculate statistics.
164
165
Parameters:
166
- start: Start date
167
- end: End date
168
"""
169
170
def display(self):
171
"""Display comparative statistics table."""
172
173
def display_lookback_returns(self):
174
"""Display lookback returns for all series."""
175
176
def plot(self, freq='D', figsize=None, title=None, logy=False, **kwargs):
177
"""
178
Plot all series on same chart.
179
180
Parameters:
181
- freq (str): Frequency for resampling
182
- figsize (tuple): Figure size
183
- title (str): Plot title
184
- logy (bool): Use logarithmic y-axis
185
- **kwargs: Additional matplotlib arguments
186
"""
187
188
def plot_scatter_matrix(self, freq='D', title=None, figsize=None, **kwargs):
189
"""
190
Create scatter plot matrix showing correlations.
191
192
Parameters:
193
- freq (str): Frequency for resampling
194
- title (str): Plot title
195
- figsize (tuple): Figure size
196
- **kwargs: Additional matplotlib arguments
197
"""
198
199
def plot_histograms(self, freq='D', title=None, figsize=None, **kwargs):
200
"""
201
Plot histogram matrix for return distributions.
202
203
Parameters:
204
- freq (str): Frequency for resampling
205
- title (str): Plot title
206
- figsize (tuple): Figure size
207
- **kwargs: Additional matplotlib arguments
208
"""
209
210
def plot_correlation(self, freq='D', title=None, figsize=None, **kwargs):
211
"""
212
Plot correlation heatmap.
213
214
Parameters:
215
- freq (str): Frequency for resampling
216
- title (str): Plot title
217
- figsize (tuple): Figure size
218
- **kwargs: Additional matplotlib arguments
219
"""
220
221
def to_csv(self, sep=',', path=None):
222
"""
223
Export comparative statistics to CSV.
224
225
Parameters:
226
- sep (str): Column separator
227
- path (str): File path (if None, returns string)
228
"""
229
```
230
231
**Key Properties:**
232
- `stats`: DataFrame with statistics for each series (rows=stats, columns=series)
233
- `lookback_returns`: DataFrame with lookback returns for all series
234
- `prices`: Merged and rebased prices DataFrame
235
236
### Convenience Functions
237
238
High-level functions for quick performance analysis without manually creating class instances.
239
240
```python { .api }
241
def calc_perf_stats(prices, risk_free_rate=0.0, annualization_factor=252):
242
"""
243
Calculate PerformanceStats object for given prices.
244
245
Parameters:
246
- prices (pd.Series): Price series
247
- risk_free_rate (float): Risk-free rate (default: 0.0)
248
- annualization_factor (int): Annualization factor (default: 252)
249
250
Returns:
251
PerformanceStats object
252
"""
253
254
def calc_stats(prices):
255
"""
256
Calculate PerformanceStats or GroupStats based on input type.
257
258
Parameters:
259
- prices (pd.Series or pd.DataFrame): Price data
260
261
Returns:
262
PerformanceStats if Series input, GroupStats if DataFrame input
263
"""
264
```
265
266
## Usage Examples
267
268
### Single Asset Analysis
269
270
```python
271
import ffn
272
273
# Download and analyze single stock
274
prices = ffn.get('AAPL', start='2020-01-01')['AAPL']
275
perf = ffn.calc_perf_stats(prices, risk_free_rate=0.02)
276
277
# Display comprehensive statistics
278
perf.display()
279
280
# Access specific metrics
281
print(f"CAGR: {perf.cagr:.2%}")
282
print(f"Max Drawdown: {perf.max_drawdown:.2%}")
283
print(f"Sharpe Ratio: {perf.sharpe:.2f}")
284
285
# Generate plots
286
perf.plot(title='AAPL Price Performance')
287
perf.plot_histogram(title='AAPL Return Distribution')
288
```
289
290
### Multi-Asset Comparison
291
292
```python
293
import ffn
294
295
# Download multiple assets
296
prices = ffn.get('AAPL,MSFT,GOOGL', start='2020-01-01')
297
298
# Create comparative analysis
299
group = ffn.GroupStats(prices['AAPL'], prices['MSFT'], prices['GOOGL'])
300
301
# Display comparative statistics
302
group.display()
303
304
# Visualization
305
group.plot(title='Tech Stock Comparison')
306
group.plot_correlation(title='Correlation Matrix')
307
group.plot_scatter_matrix(title='Return Relationships')
308
```