or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

algorithm-components.mdbacktesting-engine.mdcore-framework.mdindex.mdspecialized-securities.md

backtesting-engine.mddocs/

0

# Backtesting Engine

1

2

Core backtesting functionality for combining strategies with data, executing backtests, and analyzing results. The engine provides comprehensive statistics, visualization capabilities, and specialized result analysis tools.

3

4

## Capabilities

5

6

### Main Backtesting Class

7

8

The primary class for combining strategies with historical data to produce backtest results.

9

10

```python { .api }

11

class Backtest:

12

"""

13

Main backtesting class that combines strategy with data.

14

15

Args:

16

strategy: Strategy instance to backtest

17

data: Historical price data (DataFrame)

18

name (str, optional): Backtest name

19

initial_capital (float): Starting capital (default 1,000,000)

20

commissions (callable, optional): Commission calculation function

21

integer_positions (bool): Whether to use integer position sizes

22

progress_bar (bool): Show progress during execution

23

additional_data (dict, optional): Additional data for strategy use

24

"""

25

def __init__(self, strategy, data, name=None, initial_capital=1000000.0,

26

commissions=None, integer_positions=True, progress_bar=False,

27

additional_data=None): ...

28

29

def run(self):

30

"""Execute the backtest."""

31

...

32

33

# Properties

34

@property

35

def strategy(self): ...

36

@property

37

def data(self): ...

38

@property

39

def dates(self): ...

40

@property

41

def initial_capital(self) -> float: ...

42

@property

43

def name(self) -> str: ...

44

@property

45

def stats(self): ...

46

@property

47

def has_run(self) -> bool: ...

48

@property

49

def weights(self): ...

50

@property

51

def positions(self): ...

52

@property

53

def security_weights(self): ...

54

@property

55

def herfindahl_index(self): ...

56

@property

57

def turnover(self): ...

58

@property

59

def additional_data(self): ...

60

```

61

62

### Backtest Execution

63

64

Primary function for running multiple backtests and comparing results.

65

66

```python { .api }

67

def run(*backtests):

68

"""

69

Run multiple backtests and return Result object.

70

71

Args:

72

*backtests: Variable number of Backtest instances

73

74

Returns:

75

Result: Combined results object for analysis

76

"""

77

...

78

```

79

80

### Result Analysis Class

81

82

Comprehensive results container with analysis and visualization capabilities.

83

84

```python { .api }

85

class Result:

86

"""

87

Results analysis class inheriting from ffn.GroupStats.

88

Container for backtest results with analysis capabilities.

89

90

Args:

91

*backtests: Variable number of completed Backtest instances

92

"""

93

def __init__(self, *backtests): ...

94

95

def display_monthly_returns(self, backtest=0):

96

"""

97

Display monthly return table.

98

99

Args:

100

backtest (int): Index of backtest to display

101

"""

102

...

103

104

def get_weights(self, backtest=0, filter=None):

105

"""

106

Get strategy weights over time.

107

108

Args:

109

backtest (int): Index of backtest

110

filter (callable, optional): Filter function for weights

111

112

Returns:

113

DataFrame: Weight data over time

114

"""

115

...

116

117

def plot_weights(self, backtest=0, filter=None, figsize=(15, 5), **kwds):

118

"""

119

Plot strategy weights over time.

120

121

Args:

122

backtest (int): Index of backtest

123

filter (callable, optional): Filter function for weights

124

figsize (tuple): Figure size

125

**kwds: Additional plotting arguments

126

"""

127

...

128

129

def get_security_weights(self, backtest=0, filter=None):

130

"""

131

Get security-level weights over time.

132

133

Args:

134

backtest (int): Index of backtest

135

filter (callable, optional): Filter function for weights

136

137

Returns:

138

DataFrame: Security weight data over time

139

"""

140

...

141

142

def plot_security_weights(self, backtest=0, filter=None, figsize=(15, 5), **kwds):

143

"""

144

Plot security-level weights over time.

145

146

Args:

147

backtest (int): Index of backtest

148

filter (callable, optional): Filter function for weights

149

figsize (tuple): Figure size

150

**kwds: Additional plotting arguments

151

"""

152

...

153

154

def plot_histogram(self, backtest=0, **kwds):

155

"""

156

Plot return histogram.

157

158

Args:

159

backtest (int): Index of backtest

160

**kwds: Additional plotting arguments

161

"""

162

...

163

164

def get_transactions(self, strategy_name=None):

165

"""

166

Get transaction data for analysis.

167

168

Args:

169

strategy_name (str, optional): Specific strategy name to filter

170

171

Returns:

172

DataFrame: Transaction history

173

"""

174

...

175

176

# Properties

177

@property

178

def backtest_list(self) -> list: ...

179

@property

180

def backtests(self) -> dict: ...

181

```

182

183

### Benchmarking Functions

184

185

Utilities for comparing strategies against random benchmarks.

186

187

```python { .api }

188

def benchmark_random(backtest, random_strategy, nsim=100):

189

"""

190

Benchmark strategy against random portfolios.

191

192

Args:

193

backtest: Backtest instance to benchmark

194

random_strategy: Random strategy for comparison

195

nsim (int): Number of random simulations

196

197

Returns:

198

RandomBenchmarkResult: Benchmarking results

199

"""

200

...

201

202

class RandomBenchmarkResult(Result):

203

"""

204

Results for random strategy benchmarking.

205

206

Args:

207

*backtests: Backtest instances including base and random strategies

208

"""

209

def __init__(self, *backtests): ...

210

211

def plot_histogram(self, statistic="monthly_sharpe", figsize=(15, 5),

212

title=None, bins=20, **kwargs):

213

"""

214

Plot benchmark histogram comparing strategy to random portfolios.

215

216

Args:

217

statistic (str): Statistic to compare

218

figsize (tuple): Figure size

219

title (str, optional): Plot title

220

bins (int): Number of histogram bins

221

**kwargs: Additional plotting arguments

222

"""

223

...

224

225

# Properties

226

@property

227

def base_name(self) -> str: ...

228

@property

229

def r_stats(self): ... # Random strategy statistics

230

@property

231

def b_stats(self): ... # Base strategy statistics

232

```

233

234

### Fixed Income Results

235

236

Specialized result class for fixed income strategy analysis with renormalization.

237

238

```python { .api }

239

class RenormalizedFixedIncomeResult(Result):

240

"""

241

Results for comparing FixedIncomeStrategy with different normalizations.

242

243

Args:

244

normalizing_value: Value used for renormalization

245

*backtests: Backtest instances to compare

246

"""

247

def __init__(self, normalizing_value, *backtests): ...

248

249

def _price(self, s, v):

250

"""Internal price calculation with renormalization."""

251

...

252

```

253

254

## Usage Examples

255

256

### Basic Backtesting

257

258

```python

259

import bt

260

import pandas as pd

261

262

# Get data

263

data = bt.get('SPY,TLT', start='2010-01-01', end='2020-01-01')

264

265

# Create strategy

266

strategy = bt.Strategy('EqualWeight', [

267

bt.algos.RunMonthly(),

268

bt.algos.SelectAll(),

269

bt.algos.WeighEqually(),

270

bt.algos.Rebalance()

271

])

272

273

# Run backtest

274

backtest = bt.Backtest(strategy, data, initial_capital=100000)

275

result = bt.run(backtest)

276

277

# Analyze results

278

print(result.stats)

279

result.plot()

280

result.display_monthly_returns()

281

```

282

283

### Multiple Strategy Comparison

284

285

```python

286

# Create multiple strategies

287

equal_weight = bt.Strategy('EqualWeight', [

288

bt.algos.RunMonthly(),

289

bt.algos.SelectAll(),

290

bt.algos.WeighEqually(),

291

bt.algos.Rebalance()

292

])

293

294

risk_parity = bt.Strategy('RiskParity', [

295

bt.algos.RunMonthly(),

296

bt.algos.SelectAll(),

297

bt.algos.WeighInvVol(),

298

bt.algos.Rebalance()

299

])

300

301

# Run multiple backtests

302

bt1 = bt.Backtest(equal_weight, data)

303

bt2 = bt.Backtest(risk_parity, data)

304

result = bt.run(bt1, bt2)

305

306

# Compare results

307

result.plot()

308

result.display()

309

```

310

311

### Custom Commission Functions

312

313

```python

314

def custom_commission(quantity, price):

315

"""Custom commission: $0.01 per share, min $1."""

316

return max(abs(quantity) * 0.01, 1.0)

317

318

# Use in backtest

319

backtest = bt.Backtest(strategy, data, commissions=custom_commission)

320

result = bt.run(backtest)

321

```

322

323

### Weight Analysis

324

325

```python

326

# Analyze strategy weights over time

327

result = bt.run(backtest)

328

329

# Get weights data

330

weights = result.get_weights(0)

331

print(weights.head())

332

333

# Plot weights

334

result.plot_weights(0, figsize=(12, 6))

335

336

# Get security-level weights

337

sec_weights = result.get_security_weights(0)

338

result.plot_security_weights(0)

339

```

340

341

### Transaction Analysis

342

343

```python

344

# Get transaction history

345

transactions = result.get_transactions()

346

print(transactions.head())

347

348

# Analyze turnover

349

print(f"Average monthly turnover: {backtest.turnover.mean():.2%}")

350

351

# Plot turnover over time

352

backtest.turnover.plot(title='Monthly Turnover')

353

```

354

355

### Random Benchmarking

356

357

```python

358

# Create random strategy for benchmarking

359

random_strat = bt.Strategy('Random', [

360

bt.algos.RunMonthly(),

361

bt.algos.SelectAll(),

362

bt.algos.WeighRandomly(),

363

bt.algos.Rebalance()

364

])

365

366

# Benchmark against random portfolios

367

benchmark_result = bt.benchmark_random(backtest, random_strat, nsim=1000)

368

benchmark_result.plot_histogram('monthly_sharpe', bins=50)

369

```

370

371

### Performance Statistics

372

373

The Result class inherits from ffn.GroupStats, providing access to comprehensive performance statistics:

374

375

```python

376

# Access built-in statistics

377

stats = result.stats

378

print(f"Total Return: {stats.loc['total_return'].iloc[0]:.2%}")

379

print(f"Sharpe Ratio: {stats.loc['monthly_sharpe'].iloc[0]:.2f}")

380

print(f"Max Drawdown: {stats.loc['max_drawdown'].iloc[0]:.2%}")

381

print(f"Volatility: {stats.loc['monthly_vol'].iloc[0]:.2%}")

382

383

# Plot equity curves

384

result.plot()

385

386

# Plot drawdown

387

result.plot_histogram()

388

```