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
aponyx/__init__.py ADDED
@@ -0,0 +1,14 @@
1
+ """
2
+ Aponyx - Systematic Macro Credit Strategy Framework.
3
+
4
+ A modular Python framework for developing and backtesting systematic credit strategies.
5
+ """
6
+
7
+ from importlib.metadata import version
8
+
9
+ __version__ = version("aponyx")
10
+
11
+
12
+ def hello() -> str:
13
+ """Return greeting message."""
14
+ return "Hello from aponyx!"
@@ -0,0 +1,31 @@
1
+ """
2
+ Backtesting engine for CDX overlay strategy.
3
+
4
+ This module provides a lightweight backtesting framework optimized for
5
+ credit index strategies. The design prioritizes transparency and extensibility,
6
+ with clean interfaces that can wrap more powerful libraries later.
7
+
8
+ Core Components
9
+ ---------------
10
+ - engine: Position generation and P&L simulation
11
+ - config: Backtest parameters and constraints
12
+ - protocols: Abstract interfaces for extensibility
13
+ - registry: Strategy catalog management
14
+
15
+ Note: Performance metrics have been moved to aponyx.evaluation.performance
16
+ """
17
+
18
+ from .config import BacktestConfig
19
+ from .engine import run_backtest, BacktestResult
20
+ from .protocols import BacktestEngine, PerformanceCalculator
21
+ from .registry import StrategyRegistry, StrategyMetadata
22
+
23
+ __all__ = [
24
+ "BacktestConfig",
25
+ "run_backtest",
26
+ "BacktestResult",
27
+ "BacktestEngine",
28
+ "PerformanceCalculator",
29
+ "StrategyRegistry",
30
+ "StrategyMetadata",
31
+ ]
@@ -0,0 +1,77 @@
1
+ """
2
+ Protocol interfaces for third-party backtest library integration.
3
+
4
+ Defines protocols for backtest engines and portfolio simulators,
5
+ enabling future integration with vectorbt, bt, or other backtesting
6
+ frameworks without modifying core code.
7
+ """
8
+
9
+ from typing import Protocol
10
+
11
+ import pandas as pd
12
+
13
+ from .config import BacktestConfig
14
+ from .engine import BacktestResult
15
+
16
+
17
+ class BacktestEngine(Protocol):
18
+ """
19
+ Protocol for backtest execution engines.
20
+
21
+ Defines interface for running backtests from signal data.
22
+ Enables integration with third-party libraries like vectorbt
23
+ or custom simulation engines.
24
+
25
+ Examples
26
+ --------
27
+ >>> class VectorBTAdapter:
28
+ ... def run(
29
+ ... self,
30
+ ... signal: pd.Series,
31
+ ... spread: pd.Series,
32
+ ... config: BacktestConfig | None = None,
33
+ ... ) -> BacktestResult:
34
+ ... import vectorbt as vbt
35
+ ... entries = signal > config.entry_threshold
36
+ ... exits = signal.abs() < config.exit_threshold
37
+ ... portfolio = vbt.Portfolio.from_signals(
38
+ ... close=spread,
39
+ ... entries=entries,
40
+ ... exits=exits,
41
+ ... size=config.position_size,
42
+ ... fees=config.transaction_cost_bps / 10000,
43
+ ... )
44
+ ... # Convert vectorbt results to BacktestResult
45
+ ... return BacktestResult(...)
46
+ """
47
+
48
+ def run(
49
+ self,
50
+ signal: pd.Series,
51
+ spread: pd.Series,
52
+ config: BacktestConfig | None = None,
53
+ ) -> BacktestResult:
54
+ """
55
+ Execute backtest from signal data.
56
+
57
+ Parameters
58
+ ----------
59
+ signal : pd.Series
60
+ Trading signal with DatetimeIndex.
61
+ spread : pd.Series
62
+ Market spread data with DatetimeIndex.
63
+ config : BacktestConfig | None
64
+ Backtest configuration parameters.
65
+
66
+ Returns
67
+ -------
68
+ BacktestResult
69
+ Standardized backtest results.
70
+ """
71
+ ...
72
+
73
+
74
+ # Future adapter implementations:
75
+ # - VectorBTBacktestEngine
76
+ # - ZiplineBacktestEngine
77
+ # - CustomEventDrivenEngine
@@ -0,0 +1,84 @@
1
+ """
2
+ Configuration for backtest engine.
3
+ """
4
+
5
+ from dataclasses import dataclass
6
+
7
+
8
+ @dataclass(frozen=True)
9
+ class BacktestConfig:
10
+ """
11
+ Backtest parameters and trading constraints.
12
+
13
+ Attributes
14
+ ----------
15
+ position_size_mm : float
16
+ Notional position size in millions (e.g., 10.0 = $10MM).
17
+ sizing_mode : str
18
+ Position sizing mode: 'binary' (full position for any non-zero signal)
19
+ or 'proportional' (scaled by signal magnitude).
20
+ stop_loss_pct : float | None
21
+ Stop loss as percentage of initial position value. None to disable.
22
+ take_profit_pct : float | None
23
+ Take profit as percentage of initial position value. None to disable.
24
+ max_holding_days : int | None
25
+ Maximum days to hold a position before forced exit. None for no limit.
26
+ transaction_cost_bps : float
27
+ Round-trip transaction cost in basis points.
28
+ Typical CDX costs: 0.5-2.0 bps depending on liquidity.
29
+ dv01_per_million : float
30
+ DV01 per $1MM notional for risk calculations.
31
+ CDX IG 5Y with ~4.75 year duration: ~475.
32
+ signal_lag : int
33
+ Number of days to lag the signal before execution.
34
+ 0 = same-day execution (idealized), 1 = next-day execution (realistic).
35
+ Helps prevent look-ahead bias in backtests.
36
+ Default is 1 for realistic execution timing.
37
+
38
+ Notes
39
+ -----
40
+ - Signal-based triggers: non-zero signal = enter, zero signal = exit.
41
+ - Proportional sizing: position scaled by signal magnitude (default).
42
+ - Binary sizing: full position for any non-zero signal (use as runtime override).
43
+ - PnL-based exits (stop loss, take profit) trigger cooldown before re-entry.
44
+ - Transaction costs are applied symmetrically on entry and exit.
45
+ - signal_lag models realistic execution timing and prevents look-ahead bias.
46
+ """
47
+
48
+ position_size_mm: float
49
+ sizing_mode: str
50
+ stop_loss_pct: float | None
51
+ take_profit_pct: float | None
52
+ max_holding_days: int | None
53
+ transaction_cost_bps: float
54
+ dv01_per_million: float
55
+ signal_lag: int = 1
56
+
57
+ def __post_init__(self) -> None:
58
+ """Validate configuration parameters."""
59
+ if self.position_size_mm <= 0:
60
+ raise ValueError(
61
+ f"position_size_mm must be positive, got {self.position_size_mm}"
62
+ )
63
+ if self.sizing_mode not in {"binary", "proportional"}:
64
+ raise ValueError(
65
+ f"sizing_mode must be 'binary' or 'proportional', got '{self.sizing_mode}'"
66
+ )
67
+ if self.stop_loss_pct is not None and not (0 < self.stop_loss_pct <= 100):
68
+ raise ValueError(
69
+ f"stop_loss_pct must be in (0, 100], got {self.stop_loss_pct}"
70
+ )
71
+ if self.take_profit_pct is not None and not (0 < self.take_profit_pct <= 100):
72
+ raise ValueError(
73
+ f"take_profit_pct must be in (0, 100], got {self.take_profit_pct}"
74
+ )
75
+ if self.max_holding_days is not None and self.max_holding_days <= 0:
76
+ raise ValueError(
77
+ f"max_holding_days must be positive, got {self.max_holding_days}"
78
+ )
79
+ if self.transaction_cost_bps < 0:
80
+ raise ValueError(
81
+ f"transaction_cost_bps must be non-negative, got {self.transaction_cost_bps}"
82
+ )
83
+ if self.signal_lag < 0:
84
+ raise ValueError(f"signal_lag must be non-negative, got {self.signal_lag}")