aponyx 0.1.18__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. aponyx/__init__.py +14 -0
  2. aponyx/backtest/__init__.py +31 -0
  3. aponyx/backtest/adapters.py +77 -0
  4. aponyx/backtest/config.py +84 -0
  5. aponyx/backtest/engine.py +560 -0
  6. aponyx/backtest/protocols.py +101 -0
  7. aponyx/backtest/registry.py +334 -0
  8. aponyx/backtest/strategy_catalog.json +50 -0
  9. aponyx/cli/__init__.py +5 -0
  10. aponyx/cli/commands/__init__.py +8 -0
  11. aponyx/cli/commands/clean.py +349 -0
  12. aponyx/cli/commands/list.py +302 -0
  13. aponyx/cli/commands/report.py +167 -0
  14. aponyx/cli/commands/run.py +377 -0
  15. aponyx/cli/main.py +125 -0
  16. aponyx/config/__init__.py +82 -0
  17. aponyx/data/__init__.py +99 -0
  18. aponyx/data/bloomberg_config.py +306 -0
  19. aponyx/data/bloomberg_instruments.json +26 -0
  20. aponyx/data/bloomberg_securities.json +42 -0
  21. aponyx/data/cache.py +294 -0
  22. aponyx/data/fetch.py +659 -0
  23. aponyx/data/fetch_registry.py +135 -0
  24. aponyx/data/loaders.py +205 -0
  25. aponyx/data/providers/__init__.py +13 -0
  26. aponyx/data/providers/bloomberg.py +383 -0
  27. aponyx/data/providers/file.py +111 -0
  28. aponyx/data/registry.py +500 -0
  29. aponyx/data/requirements.py +96 -0
  30. aponyx/data/sample_data.py +415 -0
  31. aponyx/data/schemas.py +60 -0
  32. aponyx/data/sources.py +171 -0
  33. aponyx/data/synthetic_params.json +46 -0
  34. aponyx/data/transforms.py +336 -0
  35. aponyx/data/validation.py +308 -0
  36. aponyx/docs/__init__.py +24 -0
  37. aponyx/docs/adding_data_providers.md +682 -0
  38. aponyx/docs/cdx_knowledge_base.md +455 -0
  39. aponyx/docs/cdx_overlay_strategy.md +135 -0
  40. aponyx/docs/cli_guide.md +607 -0
  41. aponyx/docs/governance_design.md +551 -0
  42. aponyx/docs/logging_design.md +251 -0
  43. aponyx/docs/performance_evaluation_design.md +265 -0
  44. aponyx/docs/python_guidelines.md +786 -0
  45. aponyx/docs/signal_registry_usage.md +369 -0
  46. aponyx/docs/signal_suitability_design.md +558 -0
  47. aponyx/docs/visualization_design.md +277 -0
  48. aponyx/evaluation/__init__.py +11 -0
  49. aponyx/evaluation/performance/__init__.py +24 -0
  50. aponyx/evaluation/performance/adapters.py +109 -0
  51. aponyx/evaluation/performance/analyzer.py +384 -0
  52. aponyx/evaluation/performance/config.py +320 -0
  53. aponyx/evaluation/performance/decomposition.py +304 -0
  54. aponyx/evaluation/performance/metrics.py +761 -0
  55. aponyx/evaluation/performance/registry.py +327 -0
  56. aponyx/evaluation/performance/report.py +541 -0
  57. aponyx/evaluation/suitability/__init__.py +67 -0
  58. aponyx/evaluation/suitability/config.py +143 -0
  59. aponyx/evaluation/suitability/evaluator.py +389 -0
  60. aponyx/evaluation/suitability/registry.py +328 -0
  61. aponyx/evaluation/suitability/report.py +398 -0
  62. aponyx/evaluation/suitability/scoring.py +367 -0
  63. aponyx/evaluation/suitability/tests.py +303 -0
  64. aponyx/examples/01_generate_synthetic_data.py +53 -0
  65. aponyx/examples/02_fetch_data_file.py +82 -0
  66. aponyx/examples/03_fetch_data_bloomberg.py +104 -0
  67. aponyx/examples/04_compute_signal.py +164 -0
  68. aponyx/examples/05_evaluate_suitability.py +224 -0
  69. aponyx/examples/06_run_backtest.py +242 -0
  70. aponyx/examples/07_analyze_performance.py +214 -0
  71. aponyx/examples/08_visualize_results.py +272 -0
  72. aponyx/main.py +7 -0
  73. aponyx/models/__init__.py +45 -0
  74. aponyx/models/config.py +83 -0
  75. aponyx/models/indicator_transformation.json +52 -0
  76. aponyx/models/indicators.py +292 -0
  77. aponyx/models/metadata.py +447 -0
  78. aponyx/models/orchestrator.py +213 -0
  79. aponyx/models/registry.py +860 -0
  80. aponyx/models/score_transformation.json +42 -0
  81. aponyx/models/signal_catalog.json +29 -0
  82. aponyx/models/signal_composer.py +513 -0
  83. aponyx/models/signal_transformation.json +29 -0
  84. aponyx/persistence/__init__.py +16 -0
  85. aponyx/persistence/json_io.py +132 -0
  86. aponyx/persistence/parquet_io.py +378 -0
  87. aponyx/py.typed +0 -0
  88. aponyx/reporting/__init__.py +10 -0
  89. aponyx/reporting/generator.py +517 -0
  90. aponyx/visualization/__init__.py +20 -0
  91. aponyx/visualization/app.py +37 -0
  92. aponyx/visualization/plots.py +309 -0
  93. aponyx/visualization/visualizer.py +242 -0
  94. aponyx/workflows/__init__.py +18 -0
  95. aponyx/workflows/concrete_steps.py +720 -0
  96. aponyx/workflows/config.py +122 -0
  97. aponyx/workflows/engine.py +279 -0
  98. aponyx/workflows/registry.py +116 -0
  99. aponyx/workflows/steps.py +180 -0
  100. aponyx-0.1.18.dist-info/METADATA +552 -0
  101. aponyx-0.1.18.dist-info/RECORD +104 -0
  102. aponyx-0.1.18.dist-info/WHEEL +4 -0
  103. aponyx-0.1.18.dist-info/entry_points.txt +2 -0
  104. aponyx-0.1.18.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,455 @@
1
+ # CDX Knowledge Base
2
+
3
+ > Comprehensive reference for Credit Default Index Swaps (CDX) trading and P&L calculation
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [What is CDX?](#what-is-cdx)
10
+ 2. [CDX Index Family](#cdx-index-family)
11
+ 3. [Key Terminology](#key-terminology)
12
+ 4. [DV01 and Risk Metrics](#dv01-and-risk-metrics)
13
+ 5. [P&L Calculation](#pnl-calculation)
14
+ 6. [Transaction Costs](#transaction-costs)
15
+ 7. [Trading Conventions](#trading-conventions)
16
+ 8. [Signal Interpretation](#signal-interpretation)
17
+ 9. [Project Implementation](#project-implementation)
18
+
19
+ ---
20
+
21
+ ## What is CDX?
22
+
23
+ **Credit Default Index Swaps (CDX)** are tradeable credit derivative indices that reference a basket of single-name credit default swaps (CDS). They provide standardized exposure to corporate credit risk in North American markets.
24
+
25
+ ### How CDX Works
26
+
27
+ 1. **Protection Buyer**: Pays periodic premium (spread) to protection seller
28
+ 2. **Protection Seller**: Receives spread, pays out if credit event occurs
29
+ 3. **Credit Events**: Bankruptcy, failure to pay, restructuring (for some contracts)
30
+
31
+ ### Why Trade CDX?
32
+
33
+ - **Liquidity**: Most liquid credit derivatives (tight bid-ask spreads)
34
+ - **Standardization**: Fixed composition, maturity, coupon
35
+ - **Capital Efficiency**: Margin-based trading, no upfront principal
36
+ - **Hedging**: Efficiently hedge credit portfolio risk
37
+ - **Speculation**: Express directional views on credit markets
38
+
39
+ ---
40
+
41
+ ## CDX Index Family
42
+
43
+ ### North American Indices
44
+
45
+ | Index | Description | Typical Spread Range | DV01 per $1MM |
46
+ |-------|-------------|---------------------|---------------|
47
+ | **CDX.NA.IG** | 125 Investment Grade names | 50-150 bps | ~$450-520 |
48
+ | **CDX.NA.HY** | 100 High Yield names | 300-600 bps | ~$350-450 |
49
+ | **CDX.NA.XO** | Crossover (BB-rated) | 200-400 bps | ~$400-480 |
50
+
51
+ ### Tenors
52
+
53
+ - **5-Year**: Most liquid, primary trading vehicle
54
+ - **10-Year**: Less liquid, used for curve trades
55
+ - **3-Year, 7-Year**: Available but limited liquidity
56
+
57
+ ### Index Rolls
58
+
59
+ - CDX indices roll **every 6 months** (March and September)
60
+ - New series issued with updated constituent list
61
+ - On-the-run series has best liquidity
62
+ - Off-the-run series trade at discount
63
+
64
+ ---
65
+
66
+ ## Key Terminology
67
+
68
+ ### Spread
69
+
70
+ The **spread** is the annual premium paid by the protection buyer, quoted in basis points (bps).
71
+
72
+ ```
73
+ Spread = 100 bps means paying 1% per year on notional
74
+ For $10MM notional: $100,000/year = ~$274/day
75
+ ```
76
+
77
+ ### Spread Movements
78
+
79
+ | Movement | What It Means | Market Sentiment |
80
+ |----------|---------------|------------------|
81
+ | **Spreads Widen** | Credit risk increasing | Risk-off, bearish credit |
82
+ | **Spreads Tighten** | Credit risk decreasing | Risk-on, bullish credit |
83
+
84
+ ### Price vs. Spread
85
+
86
+ CDX can be quoted as **price** (like a bond) or **spread** (like CDS):
87
+
88
+ ```
89
+ Price ≈ 100 - (Spread × Duration)
90
+
91
+ Example: If spread = 100 bps and duration = 5 years
92
+ Price ≈ 100 - (1.00 × 5) = 95
93
+ ```
94
+
95
+ ### Fixed Coupon
96
+
97
+ Modern CDX contracts have **fixed coupons**:
98
+ - **CDX IG**: 100 bps fixed coupon
99
+ - **CDX HY**: 500 bps fixed coupon
100
+
101
+ The difference between market spread and fixed coupon is settled upfront.
102
+
103
+ ---
104
+
105
+ ## DV01 and Risk Metrics
106
+
107
+ ### What is DV01?
108
+
109
+ **DV01** (Dollar Value of 01) is the P&L impact of a 1 basis point move in spreads.
110
+
111
+ ```
112
+ DV01 = Notional × Duration × 0.0001
113
+
114
+ For CDX IG 5Y with ~4.75 year duration:
115
+ DV01 per $1MM = $1,000,000 × 4.75 × 0.0001 = $475
116
+ ```
117
+
118
+ ### Typical DV01 Values
119
+
120
+ | Index | Tenor | DV01 per $1MM | Notes |
121
+ |-------|-------|---------------|-------|
122
+ | CDX IG | 5Y | ~$475 | Primary trading vehicle |
123
+ | CDX IG | 10Y | ~$850 | Higher duration exposure |
124
+ | CDX HY | 5Y | ~$400 | Lower due to wider spreads |
125
+
126
+ ### DV01 in Aponyx
127
+
128
+ The project uses `dv01_per_million = 475.0` in the strategy catalog, representing the actual DV01 per $1MM for CDX IG 5Y:
129
+
130
+ ```json
131
+ // strategy_catalog.json
132
+ {
133
+ "name": "balanced",
134
+ "dv01_per_million": 475.0, // $475 per bp per $1MM
135
+ ...
136
+ }
137
+ ```
138
+
139
+ BacktestConfig reads DV01 from the strategy catalog (no hardcoded default).
140
+
141
+ ---
142
+
143
+ ## P&L Calculation
144
+
145
+ ### Core P&L Formula
146
+
147
+ For a **long credit risk position** (sold protection / bought CDX):
148
+
149
+ ```
150
+ Daily P&L = -Position × ΔSpread × DV01 × Notional_MM
151
+ ```
152
+
153
+ Where:
154
+ - **Position**: +1 (long credit) or -1 (short credit)
155
+ - **ΔSpread**: Today's spread - Yesterday's spread (in bps)
156
+ - **DV01**: Dollar value per basis point per $1MM (~$475 for CDX IG 5Y)
157
+ - **Notional_MM**: Position size in millions (e.g., 10 for $10MM)
158
+
159
+ ### Why the Negative Sign?
160
+
161
+ **Long credit risk** means you **profit when spreads tighten**:
162
+ - Spreads tighten (ΔSpread < 0) → P&L > 0 (profit)
163
+ - Spreads widen (ΔSpread > 0) → P&L < 0 (loss)
164
+
165
+ The negative sign converts spread direction to profit direction.
166
+
167
+ ### P&L Examples
168
+
169
+ **Example 1: Long Position, Spreads Tighten**
170
+ ```
171
+ Position: Long $10MM CDX IG 5Y
172
+ Yesterday's spread: 100 bps
173
+ Today's spread: 98 bps
174
+ ΔSpread: -2 bps
175
+ DV01: $475 per $1MM
176
+
177
+ P&L = -1 × (-2) × 475 × 10
178
+ P&L = +$9,500 (profit)
179
+ ```
180
+
181
+ **Example 2: Long Position, Spreads Widen**
182
+ ```
183
+ Position: Long $10MM CDX IG 5Y
184
+ Yesterday's spread: 100 bps
185
+ Today's spread: 103 bps
186
+ ΔSpread: +3 bps
187
+
188
+ P&L = -1 × (+3) × 475 × 10
189
+ P&L = -$14,250 (loss)
190
+ ```
191
+
192
+ **Example 3: Short Position, Spreads Widen**
193
+ ```
194
+ Position: Short $10MM CDX IG 5Y
195
+ Yesterday's spread: 100 bps
196
+ Today's spread: 105 bps
197
+ ΔSpread: +5 bps
198
+
199
+ P&L = -(-1) × (+5) × 475 × 10
200
+ P&L = +$23,750 (profit)
201
+ ```
202
+
203
+ ### Implementation in Aponyx
204
+
205
+ From `src/aponyx/backtest/engine.py`:
206
+
207
+ ```python
208
+ if abs(position_before_update) > 1e-9:
209
+ spread_change = spread_level - prev_spread_before_update
210
+ if is_proportional:
211
+ # Proportional: position_before_update is actual notional in MM
212
+ spread_pnl = (
213
+ -np.sign(position_before_update)
214
+ * abs(position_before_update)
215
+ * spread_change
216
+ * config.dv01_per_million
217
+ )
218
+ else:
219
+ # Binary: position_before_update is direction indicator (+1/-1)
220
+ spread_pnl = (
221
+ -position_before_update
222
+ * spread_change
223
+ * config.dv01_per_million
224
+ * config.position_size_mm
225
+ )
226
+ else:
227
+ spread_pnl = 0.0
228
+ ```
229
+
230
+ ---
231
+
232
+ ## Transaction Costs
233
+
234
+ ### Components of CDX Trading Costs
235
+
236
+ 1. **Bid-Ask Spread**: Primary cost, ~0.5-2 bps for CDX IG
237
+ 2. **Clearing Fees**: CME/ICE clearing costs
238
+ 3. **Commission**: Broker fees
239
+ 4. **Market Impact**: For large trades
240
+
241
+ ### Typical Transaction Costs
242
+
243
+ | Index | Bid-Ask (bps) | Round-Trip Cost |
244
+ |-------|---------------|-----------------|
245
+ | CDX IG 5Y | 0.5-1.0 | 1-2 bps |
246
+ | CDX IG 10Y | 1.0-2.0 | 2-4 bps |
247
+ | CDX HY 5Y | 2.0-4.0 | 4-8 bps |
248
+
249
+ ### Cost Calculation in Aponyx
250
+
251
+ Transaction costs depend on sizing mode:
252
+
253
+ ```python
254
+ # Binary mode: cost based on full position_size_mm
255
+ cost = transaction_cost_bps * position_size_mm * 100
256
+
257
+ # For $10MM position with 1 bps cost:
258
+ cost = 1.0 * 10.0 * 100 = $1,000 per entry/exit
259
+
260
+ # Proportional mode: cost based on actual traded notional
261
+ cost = abs(position_notional_mm) * transaction_cost_bps * 100
262
+
263
+ # For $5MM actual position with 1 bps cost:
264
+ cost = 5.0 * 1.0 * 100 = $500 per entry/exit
265
+ ```
266
+
267
+ Note: Costs are applied on **each** entry and exit, not round-trip.
268
+
269
+ ### Implementation
270
+
271
+ ```python
272
+ @dataclass(frozen=True)
273
+ class BacktestConfig:
274
+ transaction_cost_bps: float # Per-trade cost (entry OR exit)
275
+
276
+ # Binary mode
277
+ entry_cost = config.transaction_cost_bps * config.position_size_mm * 100
278
+ exit_cost = config.transaction_cost_bps * config.position_size_mm * 100
279
+
280
+ # Proportional mode
281
+ entry_cost = abs(current_position) * config.transaction_cost_bps * 100
282
+ exit_cost = abs(current_position) * config.transaction_cost_bps * 100
283
+ ```
284
+
285
+ ---
286
+
287
+ ## Trading Conventions
288
+
289
+ ### Position Direction
290
+
291
+ | Action | Position | Credit Risk | Profit When |
292
+ |--------|----------|-------------|-------------|
293
+ | **Buy CDX** | Long | Long credit risk | Spreads tighten |
294
+ | **Sell CDX** | Short | Short credit risk | Spreads widen |
295
+ | **Sell Protection** | Long | Long credit risk | Spreads tighten |
296
+ | **Buy Protection** | Short | Short credit risk | Spreads widen |
297
+
298
+ ### Market Quoting
299
+
300
+ CDX is typically quoted as spread in basis points:
301
+ - "CDX IG is offered at 75" means 75 bps spread
302
+ - "CDX IG traded 2 tighter" means spread narrowed by 2 bps
303
+
304
+ ### Settlement
305
+
306
+ - **T+1 settlement** for standard trades
307
+ - **Central clearing** required (CME, ICE)
308
+ - **Daily margin** based on mark-to-market
309
+
310
+ ---
311
+
312
+ ## Signal Interpretation
313
+
314
+ ### Aponyx Signal Convention
315
+
316
+ **CRITICAL**: All signals in Aponyx follow this convention:
317
+ - **Positive signal** → Long credit risk (buy CDX / sell protection)
318
+ - **Negative signal** → Short credit risk (sell CDX / buy protection)
319
+
320
+ ### Signal Examples
321
+
322
+ | Signal | Signal Value | Position | Expectation |
323
+ |--------|--------------|----------|-------------|
324
+ | CDX-ETF Basis | +2.0 | Long | CDX cheap, expect tightening |
325
+ | CDX-ETF Basis | -1.5 | Short | CDX expensive, expect widening |
326
+ | Spread Momentum | +1.2 | Long | Tightening momentum continues |
327
+ | CDX-VIX Gap | -0.8 | Short | Credit stress exceeds equity stress |
328
+
329
+ ### Signal-to-Position Logic
330
+
331
+ From the backtest engine:
332
+
333
+ ```python
334
+ # Non-zero signal = enter position
335
+ if not signal_is_zero:
336
+ if is_proportional:
337
+ target_position = signal_val * config.position_size_mm
338
+ else: # Binary mode
339
+ target_position = 1.0 if signal_val > 0 else -1.0
340
+
341
+ # Zero signal = exit position
342
+ if signal_is_zero:
343
+ exit_reason = "signal"
344
+ current_position = 0.0
345
+ ```
346
+
347
+ ---
348
+
349
+ ## Project Implementation
350
+
351
+ ### Key Files
352
+
353
+ | File | Purpose |
354
+ |------|---------|
355
+ | `backtest/engine.py` | P&L calculation, position management |
356
+ | `backtest/config.py` | BacktestConfig with DV01, costs |
357
+ | `backtest/strategy_catalog.json` | Pre-configured strategies |
358
+ | `docs/cdx_overlay_strategy.md` | Strategy design document |
359
+
360
+ ### BacktestConfig Parameters
361
+
362
+ ```python
363
+ @dataclass(frozen=True)
364
+ class BacktestConfig:
365
+ position_size_mm: float # Notional in $MM (required)
366
+ sizing_mode: str # "proportional" or "binary" (required)
367
+ stop_loss_pct: float | None # % of position value
368
+ take_profit_pct: float | None # % of position value
369
+ max_holding_days: int | None # Forced exit
370
+ transaction_cost_bps: float # Per-trade cost in bps (required)
371
+ dv01_per_million: float # DV01 per $1MM (required, ~475 for CDX IG 5Y)
372
+ signal_lag: int = 1 # Days to lag signal (0=same-day, 1=next-day)
373
+ ```
374
+
375
+ Note: All parameters except `signal_lag` must be explicitly provided. Use `StrategyRegistry.get()` to load from catalog.
376
+
377
+ ### Strategy Catalog
378
+
379
+ ```json
380
+ {
381
+ "name": "balanced",
382
+ "description": "Balanced position sizing with moderate risk management",
383
+ "position_size_mm": 10.0,
384
+ "sizing_mode": "proportional",
385
+ "stop_loss_pct": 5.0,
386
+ "take_profit_pct": 10.0,
387
+ "max_holding_days": null,
388
+ "transaction_cost_bps": 1.0,
389
+ "dv01_per_million": 475.0,
390
+ "enabled": true
391
+ }
392
+ ```
393
+
394
+ Note: `signal_lag` defaults to 1 in BacktestConfig and is not stored in the catalog.
395
+
396
+ ### Running a Backtest
397
+
398
+ ```python
399
+ from aponyx.backtest import BacktestConfig, run_backtest
400
+
401
+ # DV01 comes from strategy catalog (475.0 for CDX IG 5Y)
402
+ config = BacktestConfig(
403
+ position_size_mm=10.0,
404
+ stop_loss_pct=5.0,
405
+ dv01_per_million=475.0
406
+ )
407
+
408
+ result = run_backtest(signal, spread, config)
409
+
410
+ # Access results
411
+ print(f"Total P&L: ${result.pnl['cumulative_pnl'].iloc[-1]:,.0f}")
412
+ print(f"Number of trades: {result.metadata['summary']['n_trades']}")
413
+ ```
414
+
415
+ ---
416
+
417
+ ## Quick Reference Card
418
+
419
+ ### P&L Formula
420
+ ```
421
+ Daily P&L = -Position × ΔSpread × DV01 × Notional_MM
422
+ ```
423
+
424
+ ### DV01 Approximation
425
+ ```
426
+ DV01 per $1MM ≈ Duration × $100
427
+
428
+ CDX IG 5Y: ~4.75 × 100 = ~$475/bp per $1MM
429
+ For $10MM position: $475 × 10 = $4,750/bp
430
+ ```
431
+
432
+ ### Position Mapping
433
+ ```
434
+ Positive Signal → Long Credit → Buy CDX → Profit on Tightening
435
+ Negative Signal → Short Credit → Sell CDX → Profit on Widening
436
+ ```
437
+
438
+ ### Cost Impact
439
+ ```
440
+ Break-even move = Entry Cost (bps) + Exit Cost (bps)
441
+ With 1 bps per trade: need 2 bps total move to break even (1 entry + 1 exit)
442
+ ```
443
+
444
+ ---
445
+
446
+ ## References
447
+
448
+ - S&P Global: CDS Indices Primer
449
+ - IHS Markit: CDX Index Methodology
450
+ - CME Group: CDX Index Futures Specifications
451
+ - Aponyx Strategy Design: `docs/cdx_overlay_strategy.md`
452
+
453
+ ---
454
+
455
+ *Last Updated: December 2025*
@@ -0,0 +1,135 @@
1
+ # Pilot Systematic CDX Overlay Strategy
2
+
3
+ ## 1. Objective and Role
4
+
5
+ **Investment Objective:**
6
+ The pilot aims to generate short-term tactical alpha by exploiting temporary dislocations in liquid credit indices, while also providing a liquidity hedge and modest convexity enhancement.
7
+
8
+ **Relationship to Core Allocation:**
9
+ This overlay is faster-reacting, capital-efficient, and designed to be largely uncorrelated with the slower-moving core credit allocation. It serves as a tactical enhancer rather than a strategic allocation change.
10
+
11
+ **Investment Horizon & Turnover:**
12
+ Typical holding period is **days to a few weeks**, with moderate turnover aligned to signal persistence. The strategy emphasizes nimble positioning while maintaining disciplined exposure limits.
13
+
14
+ ---
15
+
16
+ ## 2. Scope of Instruments
17
+
18
+ **Primary Tradeable Instruments:**
19
+ - **CDX Investment Grade (IG)**: 5Y and 10Y tenors
20
+ - **CDX High Yield (HY)**: 5Y tenor
21
+ - **CDX North America ex-IG/XO (XO)**: 5Y tenor
22
+
23
+ **Signal Proxies:**
24
+ - ETFs such as **HYG** and **LQD** may be used for **signal generation only**, not direct trading, to capture market flow and basis information.
25
+
26
+ **Liquidity & Clearing Considerations:**
27
+ - Focus exclusively on indices with tight bid/ask spreads and reliable clearing.
28
+ - Monitor DV01 and margin usage to ensure efficient capital deployment and compliance with clearinghouse requirements.
29
+
30
+ ---
31
+
32
+ ## 3. Core Signals
33
+
34
+ ### 3.1 CDX-ETF Basis (`cdx_etf_basis`)
35
+ **Rationale:** Pricing gaps between ETFs and CDX indices can indicate temporary mispricing caused by fund flows or liquidity constraints.
36
+
37
+ **Signal Convention:**
38
+ - **Positive signal** = CDX cheap (wider spreads) → Long credit risk → Buy CDX (sell protection)
39
+ - **Negative signal** = CDX expensive (tighter spreads) → Short credit risk → Sell CDX (buy protection)
40
+
41
+ **Calculation:**
42
+ - Raw calculation: `CDX spread - ETF spread`
43
+ - No sign adjustment needed (natural directionality)
44
+ - Positive values indicate CDX is cheap relative to ETF
45
+
46
+ **Normalization:**
47
+ - Adjust for **ETF flows and volatility**, scaling the basis signal to capture persistent dislocations rather than transient noise.
48
+
49
+ ### 3.2 CDX-VIX Gap (`cdx_vix_gap`)
50
+ **Rationale:** Divergences between equity implied volatility (VIX) and credit spreads reflect asymmetric cross-asset stress conditions.
51
+
52
+ **Signal Convention:**
53
+ - **Positive signal** = Credit stress exceeds equity stress → Long credit risk → Buy CDX (sell protection)
54
+ - **Negative signal** = Equity stress exceeds credit stress → Short credit risk → Sell CDX (buy protection)
55
+
56
+ **Calculation:**
57
+ - Raw calculation: `(CDX deviation from mean) - (VIX deviation from mean)`
58
+ - No sign adjustment needed (natural directionality)
59
+ - Positive values indicate credit-specific stress (CDX spreads spiking relative to VIX)
60
+
61
+ **Considerations:**
62
+ - Differentiate **transient spikes** from sustained regime shifts using short-term averaging and persistence filters.
63
+
64
+ ### 3.3 Spread Momentum (`spread_momentum`)
65
+ **Rationale:** CDX spreads exhibit measurable short-horizon momentum or mean-reversion.
66
+
67
+ **Signal Convention:**
68
+ - **Positive signal** = Favorable tightening momentum → Long credit risk → Buy CDX (sell protection)
69
+ - **Negative signal** = Unfavorable widening momentum → Short credit risk → Sell CDX (buy protection)
70
+
71
+ **Calculation:**
72
+ - Raw calculation: `current_spread - past_spread` (positive when widening)
73
+ - **Sign adjustment required**: Negated during calculation because spread widening (positive change) should produce negative signal
74
+ - Formula: `signal = -(spread_change / volatility)`
75
+ - Positive values indicate spreads are tightening (bullish for credit)
76
+
77
+ **Horizon:** Typically **3–10 days**, with signals normalized for recent volatility.
78
+
79
+ ---
80
+
81
+ ## 4. Signal Integration & Positioning Logic
82
+
83
+ **Signal Standardization:**
84
+ - Convert each signal into a **z-score or percentile rank** to allow comparability.
85
+
86
+ **Signal Evaluation:**
87
+ - Each signal is evaluated independently to establish clear performance attribution.
88
+ - Signals can be combined in future experiments once individual performance is understood.
89
+
90
+ **Trade Expression:**
91
+ - **Positive signal:** Long credit risk → Buy CDX (sell protection)
92
+ - **Negative signal:** Short credit risk → Sell CDX (buy protection)
93
+ - **Neutral/reduced exposure:** When signal is weak or below threshold.
94
+
95
+ **Update Frequency:**
96
+ - Signals refreshed **daily**, with expected half-life of **3–7 days** depending on market regime.
97
+
98
+ ---
99
+
100
+ ## 5. Risk, Sizing, and Governance
101
+
102
+ **Position Sizing:**
103
+ - Scale positions by **DV01** or **volatility**, ensuring gross/net risk limits are respected.
104
+ - Typical gross risk: **0.5–2% DV01 of core portfolio**, with net directional limits tighter.
105
+
106
+ **Stop-Loss & Signal Fade:**
107
+ - Reduce or unwind positions when signals reverse or trigger pre-defined stop-loss levels.
108
+
109
+ **Liquidity & Slippage:**
110
+ - Assumes **tight CDX bid/ask spreads**, allowing rapid adjustment with minimal market impact.
111
+
112
+ **Governance:**
113
+ - Clear documentation and approval of positions separate from core allocation team.
114
+ - Regular review ensures overlay remains tactical and does not replace strategic allocations.
115
+
116
+ ---
117
+
118
+ ## 6. Evaluation Framework
119
+
120
+ **Performance Metrics:**
121
+ - Hit rate, **information ratio**, and **turnover-adjusted return**.
122
+
123
+ **Diversification:**
124
+ - Assess contribution to portfolio **risk-adjusted return** and correlation to core positions.
125
+
126
+ **Stress Testing:**
127
+ - Evaluate performance under macro shocks, volatility spikes, and ETF outflows.
128
+
129
+ **Scaling Considerations:**
130
+ - Lessons from pilot inform a **multi-signal production strategy**, including potential expansion of indices, tenors, and signal types.
131
+
132
+ ---
133
+
134
+ This brief frames the pilot as a **capital-efficient, tactical overlay** that exploits temporary mispricings in liquid CDX indices, complements the core portfolio, and has robust risk and governance controls.
135
+