0
# Specialized Securities
1
2
Advanced security types for specialized use cases including fixed income securities, hedge securities, and coupon-paying instruments. These securities provide custom valuation methods, cash flow handling, and specialized strategy behavior.
3
4
## Capabilities
5
6
### Fixed Income Securities
7
8
Securities designed for fixed income instruments with par value-based notional value calculation instead of market value.
9
10
```python { .api }
11
class FixedIncomeSecurity(SecurityBase):
12
"""
13
Fixed income security with par value-based notional value.
14
15
Inherits from SecurityBase but overrides notional value calculation
16
to use par value (PAR * position) instead of market value.
17
18
Args:
19
name (str): Security name/ticker
20
multiplier (float): Security multiplier (default 1)
21
lazy_add (bool): Whether to add to parent lazily
22
"""
23
def update(self, date, data=None, inow=None):
24
"""Update security state with fixed income specific logic."""
25
...
26
27
class FixedIncomeStrategy(Strategy):
28
"""
29
Strategy optimized for fixed income with notional weighting.
30
31
Uses notional values instead of market values for weight calculations,
32
appropriate for fixed income portfolio management.
33
34
Args:
35
name (str): Strategy name
36
algos (list, optional): Algorithm list
37
children (list, optional): Child securities
38
"""
39
def __init__(self, name: str, algos=None, children=None): ...
40
```
41
42
### Coupon-Paying Securities
43
44
Securities that handle irregular coupons and cash disbursements, tracking both price movements and cash flows.
45
46
```python { .api }
47
class CouponPayingSecurity(FixedIncomeSecurity):
48
"""
49
Security handling irregular coupons and cash disbursements.
50
51
Tracks coupon payments and holding costs in addition to price movements.
52
Inherits fixed income notional value calculation.
53
54
Args:
55
name (str): Security name/ticker
56
multiplier (float): Security multiplier (default 1)
57
fixed_income (bool): Whether to use fixed income logic (default True)
58
lazy_add (bool): Whether to add to parent lazily
59
"""
60
def __init__(self, name: str, multiplier=1, fixed_income=True, lazy_add=False): ...
61
62
def setup(self, universe, **kwargs):
63
"""Setup security with coupon data from universe."""
64
...
65
66
def update(self, date, data=None, inow=None):
67
"""Update security with coupon processing logic."""
68
...
69
70
# Properties
71
@property
72
def coupon(self): ...
73
@property
74
def coupons(self): ...
75
@property
76
def holding_cost(self): ...
77
@property
78
def holding_costs(self): ...
79
```
80
81
### Hedge Securities
82
83
Securities with zero notional value that don't contribute to strategy value calculations, useful for hedging instruments.
84
85
```python { .api }
86
class HedgeSecurity(SecurityBase):
87
"""
88
Security with zero notional value.
89
90
Hedge securities don't count toward strategy value calculations,
91
making them useful for overlay strategies and hedging instruments.
92
93
Args:
94
name (str): Security name/ticker
95
multiplier (float): Security multiplier (default 1)
96
lazy_add (bool): Whether to add to parent lazily
97
"""
98
def update(self, date, data=None, inow=None):
99
"""Update security with hedge-specific logic (zero notional value)."""
100
...
101
102
class CouponPayingHedgeSecurity(CouponPayingSecurity):
103
"""
104
Coupon-paying security with zero notional value.
105
106
Combines coupon payment handling with hedge security behavior.
107
Useful for fixed income overlay strategies.
108
109
Args:
110
name (str): Security name/ticker
111
multiplier (float): Security multiplier (default 1)
112
fixed_income (bool): Whether to use fixed income logic (default True)
113
lazy_add (bool): Whether to add to parent lazily
114
"""
115
def update(self, date, data=None, inow=None):
116
"""Update security with coupon processing and zero notional value."""
117
...
118
```
119
120
## Usage Examples
121
122
### Fixed Income Portfolio
123
124
```python
125
import bt
126
import pandas as pd
127
128
# Create fixed income securities
129
tlt = bt.FixedIncomeSecurity('TLT') # 20+ Year Treasury Bond ETF
130
iei = bt.FixedIncomeSecurity('IEI') # 3-7 Year Treasury Bond ETF
131
tip = bt.FixedIncomeSecurity('TIP') # Treasury Inflation-Protected Securities
132
133
# Create fixed income strategy
134
fi_strategy = bt.FixedIncomeStrategy('FixedIncome',
135
algos=[
136
bt.algos.RunMonthly(),
137
bt.algos.SelectAll(),
138
bt.algos.WeighEqually(),
139
bt.algos.Rebalance()
140
],
141
children=[tlt, iei, tip]
142
)
143
144
# Set notional value for portfolio
145
fi_strategy.algos.insert(0, bt.algos.SetNotional(10000000)) # $10M notional
146
147
# Run backtest
148
data = bt.get('TLT,IEI,TIP', start='2010-01-01', end='2020-01-01')
149
backtest = bt.Backtest(fi_strategy, data)
150
result = bt.run(backtest)
151
```
152
153
### Coupon-Paying Securities
154
155
```python
156
# Create coupon-paying security with coupon data
157
coupon_data = pd.DataFrame({
158
'BOND_COUPON': [0.025, 0.025, 0.025, 0.025], # 2.5% quarterly coupons
159
'BOND_HOLDING_COST': [0.001, 0.001, 0.001, 0.001] # Holding costs
160
}, index=pd.date_range('2020-01-01', periods=4, freq='Q'))
161
162
bond = bt.CouponPayingSecurity('BOND')
163
164
# Setup with coupon data
165
universe_data = {'BOND': price_data, 'BOND_COUPON': coupon_data['BOND_COUPON']}
166
bond.setup(universe_data)
167
168
# Create strategy
169
strategy = bt.Strategy('CouponBond',
170
algos=[
171
bt.algos.RunDaily(),
172
bt.algos.SelectAll(),
173
bt.algos.WeighEqually(),
174
bt.algos.Rebalance()
175
],
176
children=[bond]
177
)
178
```
179
180
### Hedge Overlay Strategy
181
182
```python
183
# Create main portfolio securities
184
spy = bt.Security('SPY')
185
qqq = bt.Security('QQQ')
186
187
# Create hedge securities (don't count toward portfolio value)
188
vix_hedge = bt.HedgeSecurity('VXX') # VIX hedge
189
put_hedge = bt.HedgeSecurity('PUTS') # Put option hedge
190
191
# Main strategy with hedge overlay
192
main_strategy = bt.Strategy('MainStrategy',
193
algos=[
194
bt.algos.RunMonthly(),
195
bt.algos.SelectTypes(include_types=(bt.Security,)), # Only main securities
196
bt.algos.WeighEqually(),
197
bt.algos.Rebalance()
198
],
199
children=[spy, qqq, vix_hedge, put_hedge]
200
)
201
202
# Hedge strategy (runs separately)
203
hedge_strategy = bt.Strategy('HedgeStrategy',
204
algos=[
205
bt.algos.RunDaily(),
206
bt.algos.SelectTypes(include_types=(bt.HedgeSecurity,)), # Only hedge securities
207
bt.algos.WeighSpecified(VXX=0.05, PUTS=0.02), # Small hedge positions
208
bt.algos.Rebalance()
209
],
210
parent=main_strategy
211
)
212
```
213
214
### Mixed Security Types
215
216
```python
217
# Portfolio with different security types
218
securities = [
219
bt.Security('SPY'), # Regular equity
220
bt.FixedIncomeSecurity('TLT'), # Fixed income
221
bt.CouponPayingSecurity('CORP_BOND'), # Corporate bond with coupons
222
bt.HedgeSecurity('VIX_HEDGE'), # Hedge instrument
223
bt.CouponPayingHedgeSecurity('FI_HEDGE') # Fixed income hedge with coupons
224
]
225
226
# Strategy that handles all types
227
mixed_strategy = bt.Strategy('MixedPortfolio',
228
algos=[
229
bt.algos.RunMonthly(),
230
231
# Handle regular securities
232
bt.algos.SelectTypes(include_types=(bt.Security,)),
233
bt.algos.WeighSpecified(SPY=0.6),
234
bt.algos.Rebalance(),
235
236
# Handle fixed income
237
bt.algos.SelectTypes(include_types=(bt.FixedIncomeSecurity,)),
238
bt.algos.WeighSpecified(TLT=0.3, CORP_BOND=0.1),
239
bt.algos.Rebalance(),
240
241
# Handle hedges (separate allocation)
242
bt.algos.SelectTypes(include_types=(bt.HedgeSecurity,)),
243
bt.algos.WeighSpecified(VIX_HEDGE=0.02, FI_HEDGE=0.01),
244
bt.algos.Rebalance()
245
],
246
children=securities
247
)
248
```
249
250
### Advanced Fixed Income Strategy
251
252
```python
253
# Create duration-matched fixed income portfolio
254
short_duration = bt.FixedIncomeSecurity('SHY') # 1-3 Year
255
med_duration = bt.FixedIncomeSecurity('IEI') # 3-7 Year
256
long_duration = bt.FixedIncomeSecurity('TLT') # 20+ Year
257
258
# Duration targeting strategy
259
duration_strategy = bt.FixedIncomeStrategy('DurationTarget',
260
algos=[
261
# Set target notional
262
bt.algos.SetNotional(1000000),
263
264
# Monthly rebalancing
265
bt.algos.RunMonthly(),
266
bt.algos.SelectAll(),
267
268
# Dynamic duration weighting based on yield curve
269
bt.algos.WeighTarget(duration_weights), # External weight calculation
270
bt.algos.Rebalance()
271
],
272
children=[short_duration, med_duration, long_duration]
273
)
274
275
# Run with yield curve data
276
yield_data = bt.get('SHY,IEI,TLT', start='2010-01-01', end='2020-01-01')
277
backtest = bt.Backtest(duration_strategy, yield_data)
278
result = bt.run(backtest)
279
280
# Analyze results with fixed income focus
281
print("Portfolio Duration:", result.get_weights(0).mean())
282
result.plot_weights(0, title='Duration Allocation Over Time')
283
```
284
285
## Key Differences
286
287
### Notional Value Calculations
288
289
- **Security**: `notional_value = price * position` (market value)
290
- **FixedIncomeSecurity**: `notional_value = PAR * position` (par value)
291
- **HedgeSecurity**: `notional_value = 0` (excluded from portfolio value)
292
- **CouponPayingSecurity**: Par value + coupon tracking
293
294
### Strategy Behavior
295
296
- **Strategy**: Uses market values for weight calculations
297
- **FixedIncomeStrategy**: Uses notional values for weight calculations
298
- **Hedge securities**: Don't affect parent strategy value but can have positions
299
300
### Cash Flow Handling
301
302
- **Regular securities**: Only track price changes
303
- **Coupon-paying securities**: Track both price changes and coupon payments
304
- **Holding costs**: Additional cost tracking for financing and maintenance