or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdmomentum-indicators.mdothers-indicators.mdtrend-indicators.mdutilities.mdvolatility-indicators.mdvolume-indicators.mdwrapper-functions.md

volatility-indicators.mddocs/

0

# Volatility Indicators

1

2

Volatility-based technical indicators that measure the degree of price variation and market uncertainty. These indicators help traders assess market conditions, identify potential breakouts, determine support and resistance levels, and gauge the likelihood of significant price movements.

3

4

## Capabilities

5

6

### Average True Range (ATR)

7

8

Provides an indication of the degree of price volatility by measuring the average range between high and low prices over a specified period.

9

10

```python { .api }

11

class AverageTrueRange:

12

def __init__(self, high, low, close, window=14, fillna=False):

13

"""

14

Average True Range (ATR).

15

16

Parameters:

17

- high (Series): Dataset 'High' column

18

- low (Series): Dataset 'Low' column

19

- close (Series): Dataset 'Close' column

20

- window (int): Period for calculation (default: 14)

21

- fillna (bool): If True, fill NaN values (default: False)

22

"""

23

24

def average_true_range(self):

25

"""Returns: Series with Average True Range values"""

26

27

def average_true_range(high, low, close, window=14, fillna=False):

28

"""Functional interface for Average True Range"""

29

```

30

31

### Bollinger Bands

32

33

Volatility bands placed above and below a moving average that expand and contract based on market volatility, useful for identifying overbought and oversold conditions.

34

35

```python { .api }

36

class BollingerBands:

37

def __init__(self, close, window=20, window_dev=2, fillna=False):

38

"""

39

Bollinger Bands.

40

41

Parameters:

42

- close (Series): Dataset 'Close' column

43

- window (int): Period for moving average (default: 20)

44

- window_dev (int): Standard deviation factor (default: 2)

45

- fillna (bool): If True, fill NaN values (default: False)

46

"""

47

48

def bollinger_mavg(self):

49

"""Returns: Series with Bollinger Channel Middle Band (SMA)"""

50

51

def bollinger_hband(self):

52

"""Returns: Series with Bollinger Channel High Band (Upper)"""

53

54

def bollinger_lband(self):

55

"""Returns: Series with Bollinger Channel Low Band (Lower)"""

56

57

def bollinger_wband(self):

58

"""Returns: Series with Bollinger Channel Band Width"""

59

60

def bollinger_pband(self):

61

"""Returns: Series with Bollinger Channel Percentage Band (%B)"""

62

63

def bollinger_hband_indicator(self):

64

"""Returns: Series with Bollinger High Band Indicator (binary signal)"""

65

66

def bollinger_lband_indicator(self):

67

"""Returns: Series with Bollinger Low Band Indicator (binary signal)"""

68

69

def bollinger_mavg(close, window=20, fillna=False):

70

"""Functional interface for Bollinger Middle Band"""

71

72

def bollinger_hband(close, window=20, window_dev=2, fillna=False):

73

"""Functional interface for Bollinger High Band"""

74

75

def bollinger_lband(close, window=20, window_dev=2, fillna=False):

76

"""Functional interface for Bollinger Low Band"""

77

78

def bollinger_wband(close, window=20, window_dev=2, fillna=False):

79

"""Functional interface for Bollinger Band Width"""

80

81

def bollinger_pband(close, window=20, window_dev=2, fillna=False):

82

"""Functional interface for Bollinger Percentage Band"""

83

84

def bollinger_hband_indicator(close, window=20, window_dev=2, fillna=False):

85

"""Functional interface for Bollinger High Band Indicator"""

86

87

def bollinger_lband_indicator(close, window=20, window_dev=2, fillna=False):

88

"""Functional interface for Bollinger Low Band Indicator"""

89

```

90

91

### Keltner Channel

92

93

Trend-following indicator used to identify reversals with channel breakouts and closures, based on exponential moving average and Average True Range.

94

95

```python { .api }

96

class KeltnerChannel:

97

def __init__(self, high, low, close, window=20, window_atr=10, fillna=False,

98

original_version=True, multiplier=2):

99

"""

100

Keltner Channel.

101

102

Parameters:

103

- high (Series): Dataset 'High' column

104

- low (Series): Dataset 'Low' column

105

- close (Series): Dataset 'Close' column

106

- window (int): Period for centerline calculation (default: 20)

107

- window_atr (int): Period for ATR calculation (default: 10)

108

- fillna (bool): If True, fill NaN values (default: False)

109

- original_version (bool): If True, use original version as centerline (default: False)

110

- multiplier (int): Multiplier for channel width (default: 2)

111

"""

112

113

def keltner_channel_mband(self):

114

"""Returns: Series with Keltner Channel Middle Band (centerline)"""

115

116

def keltner_channel_hband(self):

117

"""Returns: Series with Keltner Channel High Band (upper)"""

118

119

def keltner_channel_lband(self):

120

"""Returns: Series with Keltner Channel Low Band (lower)"""

121

122

def keltner_channel_wband(self):

123

"""Returns: Series with Keltner Channel Band Width"""

124

125

def keltner_channel_pband(self):

126

"""Returns: Series with Keltner Channel Percentage Band"""

127

128

def keltner_channel_hband_indicator(self):

129

"""Returns: Series with Keltner High Band Indicator (binary signal)"""

130

131

def keltner_channel_lband_indicator(self):

132

"""Returns: Series with Keltner Low Band Indicator (binary signal)"""

133

134

def keltner_channel_mband(high, low, close, window=20, window_atr=10, fillna=False,

135

original_version=False, multiplier=2):

136

"""Functional interface for Keltner Channel Middle Band"""

137

138

def keltner_channel_hband(high, low, close, window=20, window_atr=10, fillna=False,

139

original_version=False, multiplier=2):

140

"""Functional interface for Keltner Channel High Band"""

141

142

def keltner_channel_lband(high, low, close, window=20, window_atr=10, fillna=False,

143

original_version=False, multiplier=2):

144

"""Functional interface for Keltner Channel Low Band"""

145

146

def keltner_channel_wband(high, low, close, window=20, window_atr=10, fillna=False,

147

original_version=False, multiplier=2):

148

"""Functional interface for Keltner Channel Band Width"""

149

150

def keltner_channel_pband(high, low, close, window=20, window_atr=10, fillna=False,

151

original_version=False, multiplier=2):

152

"""Functional interface for Keltner Channel Percentage Band"""

153

154

def keltner_channel_hband_indicator(high, low, close, window=20, window_atr=10,

155

fillna=False, original_version=False, multiplier=2):

156

"""Functional interface for Keltner Channel High Band Indicator"""

157

158

def keltner_channel_lband_indicator(high, low, close, window=20, window_atr=10,

159

fillna=False, original_version=False, multiplier=2):

160

"""Functional interface for Keltner Channel Low Band Indicator"""

161

```

162

163

### Donchian Channel

164

165

Channel-based indicator that identifies the highest high and lowest low over a specified period, useful for breakout strategies and trend identification.

166

167

```python { .api }

168

class DonchianChannel:

169

def __init__(self, high, low, close, window=20, offset=0, fillna=False):

170

"""

171

Donchian Channel.

172

173

Parameters:

174

- high (Series): Dataset 'High' column

175

- low (Series): Dataset 'Low' column

176

- close (Series): Dataset 'Close' column

177

- window (int): Period for calculation (default: 20)

178

- offset (int): Offset for calculation (default: 0)

179

- fillna (bool): If True, fill NaN values (default: False)

180

"""

181

182

def donchian_channel_hband(self):

183

"""Returns: Series with Donchian Channel High Band (highest high)"""

184

185

def donchian_channel_lband(self):

186

"""Returns: Series with Donchian Channel Low Band (lowest low)"""

187

188

def donchian_channel_mband(self):

189

"""Returns: Series with Donchian Channel Middle Band (midpoint)"""

190

191

def donchian_channel_wband(self):

192

"""Returns: Series with Donchian Channel Band Width"""

193

194

def donchian_channel_pband(self):

195

"""Returns: Series with Donchian Channel Percentage Band"""

196

197

def donchian_channel_hband(high, low, close, window=20, offset=0, fillna=False):

198

"""Functional interface for Donchian Channel High Band"""

199

200

def donchian_channel_lband(high, low, close, window=20, offset=0, fillna=False):

201

"""Functional interface for Donchian Channel Low Band"""

202

203

def donchian_channel_mband(high, low, close, window=10, offset=0, fillna=False):

204

"""Functional interface for Donchian Channel Middle Band"""

205

206

def donchian_channel_wband(high, low, close, window=10, offset=0, fillna=False):

207

"""Functional interface for Donchian Channel Band Width"""

208

209

def donchian_channel_pband(high, low, close, window=10, offset=0, fillna=False):

210

"""Functional interface for Donchian Channel Percentage Band"""

211

```

212

213

### Ulcer Index

214

215

Measures downside risk by calculating the percentage drawdown from the highest high over a specified period, focusing on the depth and duration of drawdowns.

216

217

```python { .api }

218

class UlcerIndex:

219

def __init__(self, close, window=14, fillna=False):

220

"""

221

Ulcer Index.

222

223

Parameters:

224

- close (Series): Dataset 'Close' column

225

- window (int): Period for calculation (default: 14)

226

- fillna (bool): If True, fill NaN values (default: False)

227

"""

228

229

def ulcer_index(self):

230

"""Returns: Series with Ulcer Index values (downside risk measure)"""

231

232

def ulcer_index(close, window=14, fillna=False):

233

"""Functional interface for Ulcer Index"""

234

```

235

236

## Usage Examples

237

238

### Volatility Analysis Workflow

239

240

```python

241

from ta.volatility import *

242

import pandas as pd

243

244

def analyze_volatility(df):

245

# Basic volatility measures

246

df['ATR'] = average_true_range(df['High'], df['Low'], df['Close'])

247

df['Ulcer'] = ulcer_index(df['Close'])

248

249

# Bollinger Bands analysis

250

df['BB_Middle'] = bollinger_mavg(df['Close'])

251

df['BB_Upper'] = bollinger_hband(df['Close'])

252

df['BB_Lower'] = bollinger_lband(df['Close'])

253

df['BB_Width'] = bollinger_wband(df['Close'])

254

df['BB_Percent'] = bollinger_pband(df['Close'])

255

256

# Channel breakout indicators

257

df['Keltner_Upper'] = keltner_channel_hband(df['High'], df['Low'], df['Close'])

258

df['Keltner_Lower'] = keltner_channel_lband(df['High'], df['Low'], df['Close'])

259

df['Donchian_Upper'] = donchian_channel_hband(df['High'], df['Low'], df['Close'])

260

df['Donchian_Lower'] = donchian_channel_lband(df['High'], df['Low'], df['Close'])

261

262

return df

263

264

# Apply volatility analysis

265

df_volatility = analyze_volatility(df)

266

```

267

268

### Bollinger Band Strategy

269

270

```python

271

from ta.volatility import BollingerBands

272

273

# Create Bollinger Bands indicator

274

bb_indicator = BollingerBands(

275

close=df['Close'],

276

window=20,

277

window_dev=2

278

)

279

280

# Calculate all Bollinger Band components

281

df['BB_Middle'] = bb_indicator.bollinger_mavg()

282

df['BB_Upper'] = bb_indicator.bollinger_hband()

283

df['BB_Lower'] = bb_indicator.bollinger_lband()

284

df['BB_Width'] = bb_indicator.bollinger_wband()

285

df['BB_Percent'] = bb_indicator.bollinger_pband()

286

287

# Generate trading signals

288

df['BB_Upper_Signal'] = bb_indicator.bollinger_hband_indicator()

289

df['BB_Lower_Signal'] = bb_indicator.bollinger_lband_indicator()

290

291

# Bollinger Band squeeze detection (low volatility)

292

df['BB_Squeeze'] = df['BB_Width'] < df['BB_Width'].rolling(20).quantile(0.2)

293

294

# Bollinger Band expansion (high volatility)

295

df['BB_Expansion'] = df['BB_Width'] > df['BB_Width'].rolling(20).quantile(0.8)

296

297

# Trading signals based on band position

298

df['BB_Buy_Signal'] = (df['Close'] <= df['BB_Lower']) & (df['BB_Percent'] < 0.05)

299

df['BB_Sell_Signal'] = (df['Close'] >= df['BB_Upper']) & (df['BB_Percent'] > 0.95)

300

```

301

302

### Channel Breakout System

303

304

```python

305

from ta.volatility import KeltnerChannel, DonchianChannel

306

307

# Multi-channel breakout system

308

def channel_breakout_analysis(df):

309

# Keltner Channels

310

keltner = KeltnerChannel(

311

high=df['High'],

312

low=df['Low'],

313

close=df['Close'],

314

window=20,

315

window_atr=10,

316

multiplier=2

317

)

318

319

# Donchian Channels

320

donchian = DonchianChannel(

321

high=df['High'],

322

low=df['Low'],

323

close=df['Close'],

324

window=20

325

)

326

327

# Calculate channel values

328

df['Keltner_Upper'] = keltner.keltner_channel_hband()

329

df['Keltner_Lower'] = keltner.keltner_channel_lband()

330

df['Keltner_Middle'] = keltner.keltner_channel_mband()

331

332

df['Donchian_Upper'] = donchian.donchian_channel_hband()

333

df['Donchian_Lower'] = donchian.donchian_channel_lband()

334

df['Donchian_Middle'] = donchian.donchian_channel_mband()

335

336

# Breakout signals

337

df['Keltner_Breakout_Up'] = keltner.keltner_channel_hband_indicator()

338

df['Keltner_Breakout_Down'] = keltner.keltner_channel_lband_indicator()

339

340

# Channel width for volatility assessment

341

df['Keltner_Width'] = keltner.keltner_channel_wband()

342

df['Donchian_Width'] = donchian.donchian_channel_wband()

343

344

# Combined breakout signal (both channels agree)

345

df['Combined_Breakout_Up'] = (

346

(df['Close'] > df['Keltner_Upper']) &

347

(df['Close'] > df['Donchian_Upper'])

348

)

349

df['Combined_Breakout_Down'] = (

350

(df['Close'] < df['Keltner_Lower']) &

351

(df['Close'] < df['Donchian_Lower'])

352

)

353

354

return df

355

356

df_channels = channel_breakout_analysis(df)

357

```

358

359

### Volatility Regime Detection

360

361

```python

362

from ta.volatility import AverageTrueRange, UlcerIndex

363

364

# Advanced volatility regime analysis

365

def volatility_regime_analysis(df):

366

# Calculate volatility measures

367

atr_indicator = AverageTrueRange(

368

high=df['High'],

369

low=df['Low'],

370

close=df['Close'],

371

window=14

372

)

373

374

ulcer_indicator = UlcerIndex(

375

close=df['Close'],

376

window=14

377

)

378

379

df['ATR'] = atr_indicator.average_true_range()

380

df['Ulcer'] = ulcer_indicator.ulcer_index()

381

382

# Normalized ATR (as percentage of price)

383

df['ATR_Percent'] = (df['ATR'] / df['Close']) * 100

384

385

# Volatility percentiles for regime classification

386

df['ATR_Percentile'] = df['ATR_Percent'].rolling(252).rank(pct=True)

387

df['Ulcer_Percentile'] = df['Ulcer'].rolling(252).rank(pct=True)

388

389

# Volatility regimes

390

df['Volatility_Regime'] = pd.cut(

391

df['ATR_Percentile'],

392

bins=[0, 0.33, 0.66, 1.0],

393

labels=['Low', 'Medium', 'High']

394

)

395

396

# Risk-adjusted signals based on volatility regime

397

df['Risk_Adjusted_Position_Size'] = np.where(

398

df['Volatility_Regime'] == 'High', 0.5, # Reduce size in high vol

399

np.where(df['Volatility_Regime'] == 'Low', 1.5, 1.0) # Increase in low vol

400

)

401

402

# Downside risk assessment

403

df['High_Downside_Risk'] = df['Ulcer_Percentile'] > 0.8

404

405

return df

406

407

df_volatility_regime = volatility_regime_analysis(df)

408

```

409

410

### Multi-Timeframe Volatility Analysis

411

412

```python

413

from ta.volatility import *

414

415

# Multi-timeframe volatility assessment

416

def multi_timeframe_volatility(df):

417

# Short-term volatility (5-day)

418

df['ATR_Short'] = average_true_range(df['High'], df['Low'], df['Close'], window=5)

419

df['BB_Width_Short'] = bollinger_wband(df['Close'], window=10, window_dev=2)

420

421

# Medium-term volatility (20-day)

422

df['ATR_Medium'] = average_true_range(df['High'], df['Low'], df['Close'], window=20)

423

df['BB_Width_Medium'] = bollinger_wband(df['Close'], window=20, window_dev=2)

424

425

# Long-term volatility (50-day)

426

df['ATR_Long'] = average_true_range(df['High'], df['Low'], df['Close'], window=50)

427

df['BB_Width_Long'] = bollinger_wband(df['Close'], window=50, window_dev=2)

428

429

# Volatility term structure analysis

430

df['Vol_Term_Structure'] = df['ATR_Short'] / df['ATR_Long']

431

432

# Volatility momentum (expanding vs contracting)

433

df['Vol_Momentum'] = (

434

(df['BB_Width_Short'] > df['BB_Width_Short'].shift(5)).astype(int) +

435

(df['BB_Width_Medium'] > df['BB_Width_Medium'].shift(10)).astype(int) +

436

(df['BB_Width_Long'] > df['BB_Width_Long'].shift(20)).astype(int)

437

)

438

439

# Volatility divergence signals

440

df['Vol_Divergence'] = (

441

(df['ATR_Short'] > df['ATR_Medium']) &

442

(df['ATR_Medium'] < df['ATR_Long'])

443

)

444

445

return df

446

447

df_multi_tf_vol = multi_timeframe_volatility(df)

448

```