or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-utilities.mdindex.mdpandas-integration.mdperformance-visualization.mdreport-generation.mdrisk-assessment.mdstatistical-analysis.md

pandas-integration.mddocs/

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.