0
# Pandas Integration
1
2
Extended pandas functionality that seamlessly integrates QuantStats statistical analysis, risk assessment, plotting, and reporting capabilities directly into pandas DataFrames and Series for fluid method chaining and integrated workflows.
3
4
## Capabilities
5
6
### Pandas Extension Setup
7
8
Enable QuantStats methods on pandas objects for method chaining.
9
10
```python { .api }
11
def extend_pandas():
12
"""
13
Extend pandas DataFrames and Series with QuantStats methods.
14
15
This function adds all QuantStats statistical, plotting, and utility functions
16
as methods to pandas PandasObject, enabling method chaining syntax.
17
18
After calling this function, you can use QuantStats functions directly on
19
pandas objects: df.sharpe(), series.max_drawdown(), etc.
20
21
Returns:
22
None
23
"""
24
```
25
26
## Extended Methods Available After `extend_pandas()`
27
28
Once `extend_pandas()` is called, all the following methods become available on pandas DataFrames and Series:
29
30
### Statistical Analysis Methods
31
32
All statistical functions from `quantstats.stats` become available as DataFrame/Series methods:
33
34
```python { .api }
35
# Performance ratios
36
.sharpe(rf=0.0, periods=252, annualize=True, smart=False)
37
.sortino(rf=0, periods=252, annualize=True, smart=False)
38
.calmar(prepare_returns=True, periods=252)
39
.treynor_ratio(benchmark, periods=252.0, rf=0.0)
40
.omega(rf=0.0, required_return=0.0, periods=252)
41
42
# Risk metrics
43
.volatility(periods=252, annualize=True, prepare_returns=True)
44
.max_drawdown()
45
.value_at_risk(sigma=1, confidence=0.95, prepare_returns=True)
46
.var(sigma=1, confidence=0.95, prepare_returns=True)
47
.conditional_value_at_risk(sigma=1, confidence=0.95, prepare_returns=True)
48
.cvar(sigma=1, confidence=0.95, prepare_returns=True)
49
50
# Return analysis
51
.cagr(rf=0.0, compounded=True, periods=252)
52
.expected_return(aggregate=None, compounded=True, prepare_returns=True)
53
.avg_return(aggregate=None, compounded=True, prepare_returns=True)
54
.best(aggregate=None, compounded=True, prepare_returns=True)
55
.worst(aggregate=None, compounded=True, prepare_returns=True)
56
57
# Win/loss analysis
58
.win_rate(aggregate=None, compounded=True, prepare_returns=True)
59
.avg_win(aggregate=None, compounded=True, prepare_returns=True)
60
.avg_loss(aggregate=None, compounded=True, prepare_returns=True)
61
.consecutive_wins(aggregate=None, compounded=True, prepare_returns=True)
62
.consecutive_losses(aggregate=None, compounded=True, prepare_returns=True)
63
64
# Advanced metrics
65
.kelly_criterion(prepare_returns=True)
66
.ulcer_index()
67
.tail_ratio(cutoff=0.95, prepare_returns=True)
68
.skew(prepare_returns=True)
69
.kurtosis(prepare_returns=True)
70
```
71
72
### Rolling Analysis Methods
73
74
Rolling window statistical calculations:
75
76
```python { .api }
77
.rolling_sharpe(rf=0, periods=252, window=126, annualize=True, prepare_returns=True)
78
.rolling_sortino(rf=0, periods=252, window=126, annualize=True, prepare_returns=True)
79
.rolling_volatility(periods=252, window=126, min_periods=None, annualize=True, prepare_returns=True)
80
.rolling_greeks(benchmark, periods=252, prepare_returns=True)
81
```
82
83
### Benchmarking Methods
84
85
Compare performance against benchmarks:
86
87
```python { .api }
88
.r_squared(benchmark, prepare_returns=True)
89
.r2(benchmark) # Alias for r_squared
90
.information_ratio(benchmark, prepare_returns=True)
91
.greeks(benchmark, periods=252.0, prepare_returns=True)
92
.compare(benchmark, aggregate=None, compounded=True, round_vals=None)
93
```
94
95
### Data Utility Methods
96
97
Data preparation and conversion functions:
98
99
```python { .api }
100
.to_returns(rf=0.0)
101
.to_prices(base=1e5)
102
.to_log_returns(rf=0.0, nperiods=None)
103
.log_returns(rf=0.0, nperiods=None)
104
.to_excess_returns(rf, nperiods=None)
105
.rebase(base=100.0)
106
.aggregate_returns(period=None, compounded=True)
107
.exponential_stdev(window=30, is_halflife=False)
108
.multi_shift(shift=3)
109
```
110
111
### Time-based Filtering Methods
112
113
Date filtering utilities:
114
115
```python { .api }
116
.mtd() # Month-to-date
117
.qtd() # Quarter-to-date
118
.ytd() # Year-to-date
119
.curr_month() # Current month
120
.date(dates) # Filter by specific dates
121
```
122
123
### Plotting Methods
124
125
All visualization functions with `plot_` prefix:
126
127
```python { .api }
128
.plot_snapshot(grayscale=False, figsize=(10, 8), title="Portfolio Summary", ...)
129
.plot_earnings(start_balance=1e5, mode="comp", ...)
130
.plot_returns(benchmark=None, ...)
131
.plot_daily_returns(benchmark, ...)
132
.plot_distribution(...)
133
.plot_drawdown(...)
134
.plot_drawdowns_periods(periods=5, ...)
135
.plot_histogram(benchmark=None, resample="ME", ...)
136
.plot_log_returns(benchmark=None, ...)
137
.plot_rolling_beta(benchmark, window1=126, window2=252, ...)
138
.plot_rolling_sharpe(benchmark=None, rf=0.0, period=126, ...)
139
.plot_rolling_sortino(benchmark=None, rf=0.0, period=126, ...)
140
.plot_rolling_volatility(benchmark=None, period=126, ...)
141
.plot_yearly_returns(benchmark=None, ...)
142
.plot_monthly_heatmap(benchmark=None, ...)
143
```
144
145
### Report Generation Method
146
147
Generate performance metrics:
148
149
```python { .api }
150
.metrics(benchmark=None, rf=0.0, display=True, mode="basic", compounded=True, ...)
151
```
152
153
## Usage Examples
154
155
### Method Chaining Workflow
156
157
```python
158
import quantstats as qs
159
import pandas as pd
160
import numpy as np
161
162
# Enable pandas integration
163
qs.extend_pandas()
164
165
# Create sample returns
166
dates = pd.date_range('2020-01-01', '2023-12-31', freq='D')
167
returns = pd.Series(np.random.normal(0.001, 0.02, len(dates)), index=dates)
168
169
# Use method chaining for analysis
170
analysis_results = (returns
171
.sharpe() # Calculate Sharpe ratio
172
, returns.sortino() # Calculate Sortino ratio
173
, returns.max_drawdown() # Calculate max drawdown
174
, returns.cagr() # Calculate CAGR
175
, returns.volatility() # Calculate volatility
176
)
177
178
print(f"Sharpe: {analysis_results[0]:.2f}")
179
print(f"Sortino: {analysis_results[1]:.2f}")
180
print(f"Max DD: {analysis_results[2]:.2%}")
181
print(f"CAGR: {analysis_results[3]:.2%}")
182
print(f"Volatility: {analysis_results[4]:.2%}")
183
```
184
185
### Integrated Analysis Pipeline
186
187
```python
188
# Complete analysis pipeline with method chaining
189
returns_analysis = (returns
190
.to_excess_returns(rf=0.02) # Convert to excess returns
191
.aggregate_returns('M') # Aggregate to monthly
192
)
193
194
# Statistical analysis
195
monthly_stats = {
196
'sharpe': returns_analysis.sharpe(),
197
'sortino': returns_analysis.sortino(),
198
'calmar': returns_analysis.calmar(),
199
'max_dd': returns_analysis.max_drawdown(),
200
'win_rate': returns_analysis.win_rate()
201
}
202
203
# Create visualizations
204
returns.plot_snapshot(title="Portfolio Performance")
205
returns.plot_drawdown()
206
returns.plot_monthly_heatmap()
207
```
208
209
### Benchmarking with Method Chaining
210
211
```python
212
# Download benchmark and perform comparison
213
spy_returns = qs.utils.download_returns('SPY')
214
215
# Benchmarking analysis
216
benchmark_analysis = {
217
'alpha': returns.greeks(spy_returns)['alpha'],
218
'beta': returns.greeks(spy_returns)['beta'],
219
'r_squared': returns.r_squared(spy_returns),
220
'info_ratio': returns.information_ratio(spy_returns),
221
'treynor': returns.treynor_ratio(spy_returns)
222
}
223
224
# Comparative visualization
225
returns.plot_returns(benchmark=spy_returns, title="Portfolio vs SPY")
226
returns.plot_rolling_sharpe(benchmark=spy_returns)
227
```
228
229
### Time-based Analysis
230
231
```python
232
# Time-based filtering and analysis
233
ytd_performance = returns.ytd().cagr()
234
mtd_performance = returns.mtd().cagr()
235
qtd_performance = returns.qtd().cagr()
236
237
print(f"YTD Performance: {ytd_performance:.2%}")
238
print(f"MTD Performance: {mtd_performance:.2%}")
239
print(f"QTD Performance: {qtd_performance:.2%}")
240
241
# Rolling analysis
242
rolling_metrics = pd.DataFrame({
243
'rolling_sharpe': returns.rolling_sharpe(window=252),
244
'rolling_volatility': returns.rolling_volatility(window=252),
245
'rolling_sortino': returns.rolling_sortino(window=252)
246
})
247
```
248
249
### Advanced Risk Analysis
250
251
```python
252
# Comprehensive risk assessment using method chaining
253
risk_metrics = {
254
'var_95': returns.var(confidence=0.95),
255
'cvar_95': returns.cvar(confidence=0.95),
256
'var_99': returns.var(confidence=0.99),
257
'cvar_99': returns.cvar(confidence=0.99),
258
'ulcer_index': returns.ulcer_index(),
259
'tail_ratio': returns.tail_ratio(),
260
'kelly': returns.kelly_criterion()
261
}
262
263
# Display risk metrics
264
for metric, value in risk_metrics.items():
265
print(f"{metric}: {value:.4f}")
266
```
267
268
### Complete Reporting Workflow
269
270
```python
271
# Generate comprehensive report using pandas integration
272
portfolio_report = returns.metrics(
273
benchmark=spy_returns,
274
rf=0.02,
275
mode='full'
276
)
277
278
# Create all visualizations
279
returns.plot_snapshot(title="Complete Portfolio Analysis")
280
returns.plot_distribution()
281
returns.plot_yearly_returns(benchmark=spy_returns)
282
283
# Export results
284
portfolio_report.to_csv('portfolio_metrics.csv')
285
```
286
287
## Benefits of Pandas Integration
288
289
### Seamless Workflow Integration
290
- **Method Chaining**: Combine data manipulation with quantitative analysis
291
- **Familiar Syntax**: Use QuantStats functions as natural DataFrame/Series methods
292
- **Reduced Code**: Eliminate need for function calls with explicit arguments
293
294
### Enhanced Productivity
295
- **Interactive Analysis**: Perfect for Jupyter notebooks and exploratory analysis
296
- **Pipeline Creation**: Build complex analysis pipelines with method chaining
297
- **Integration**: Works seamlessly with existing pandas-based workflows
298
299
### Consistent API
300
- **Same Parameters**: All methods accept the same parameters as their function equivalents
301
- **Same Returns**: Methods return identical results to their function counterparts
302
- **Full Coverage**: Access to all 100+ QuantStats functions as methods
303
304
## Implementation Notes
305
306
The `extend_pandas()` function works by adding methods to the `pandas.core.base.PandasObject` class, making them available to all pandas DataFrames and Series. This approach ensures compatibility with existing pandas code while providing the full power of QuantStats analytics.
307
308
All extended methods maintain the same parameter signatures and return types as their corresponding functions in the QuantStats modules, ensuring consistent behavior whether using function calls or method chaining.