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,552 @@
1
+ Metadata-Version: 2.4
2
+ Name: aponyx
3
+ Version: 0.1.18
4
+ Summary: Early-stage research framework for backtesting systematic credit strategies (not for production use)
5
+ Project-URL: Homepage, https://github.com/stabilefrisur/aponyx
6
+ Project-URL: Repository, https://github.com/stabilefrisur/aponyx
7
+ Project-URL: Documentation, https://github.com/stabilefrisur/aponyx/blob/master/README.md
8
+ Project-URL: Issues, https://github.com/stabilefrisur/aponyx/issues
9
+ Project-URL: Changelog, https://github.com/stabilefrisur/aponyx/blob/master/CHANGELOG.md
10
+ Author-email: Stabile Frisur <26568863+stabilefrisur@users.noreply.github.com>
11
+ License: MIT License
12
+
13
+ Copyright (c) 2025 Stabile Frisur
14
+
15
+ Permission is hereby granted, free of charge, to any person obtaining a copy
16
+ of this software and associated documentation files (the "Software"), to deal
17
+ in the Software without restriction, including without limitation the rights
18
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
+ copies of the Software, and to permit persons to whom the Software is
20
+ furnished to do so, subject to the following conditions:
21
+
22
+ The above copyright notice and this permission notice shall be included in all
23
+ copies or substantial portions of the Software.
24
+
25
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
+ SOFTWARE.
32
+ License-File: LICENSE
33
+ Keywords: backtesting,finance,investing,research
34
+ Classifier: Development Status :: 3 - Alpha
35
+ Classifier: Intended Audience :: Science/Research
36
+ Classifier: License :: OSI Approved :: MIT License
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Programming Language :: Python :: 3.12
39
+ Classifier: Topic :: Office/Business :: Financial :: Investment
40
+ Classifier: Typing :: Typed
41
+ Requires-Python: <3.13,>=3.12
42
+ Requires-Dist: click>=8.1.0
43
+ Requires-Dist: ipython>=8.0.0
44
+ Requires-Dist: numpy>=1.24.0
45
+ Requires-Dist: pandas>=2.0.0
46
+ Requires-Dist: pyarrow>=12.0.0
47
+ Requires-Dist: pyyaml>=6.0
48
+ Requires-Dist: quantstats>=0.0.77
49
+ Requires-Dist: scipy>=1.7.0
50
+ Requires-Dist: statsmodels>=0.14.0
51
+ Provides-Extra: bloomberg
52
+ Requires-Dist: xbbg>=0.7.0; extra == 'bloomberg'
53
+ Provides-Extra: dev
54
+ Requires-Dist: mypy>=1.19.0; extra == 'dev'
55
+ Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
56
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
57
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
58
+ Provides-Extra: viz
59
+ Requires-Dist: plotly>=5.24.0; extra == 'viz'
60
+ Description-Content-Type: text/markdown
61
+
62
+ # Aponyx
63
+
64
+ [![PyPI version](https://img.shields.io/pypi/v/aponyx.svg)](https://pypi.org/project/aponyx/)
65
+ [![Python 3.12](https://img.shields.io/badge/python-3.12-blue.svg)](https://www.python.org/downloads/)
66
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
67
+
68
+ > **Early-stage research framework** — Not for production use
69
+
70
+ **A modular Python framework for developing and backtesting systematic credit strategies.**
71
+
72
+ Type-safe, reproducible research environment for tactical fixed-income strategies with clean separation between strategy logic, data infrastructure, and backtesting workflows.
73
+
74
+ ## Key Features
75
+
76
+ - **CLI orchestrator** for automated end-to-end research workflows (run, report, list, clean)
77
+ - **Workflow engine** with smart caching and dependency tracking across pipeline steps
78
+ - **Type-safe data loading** with schema validation (Parquet, CSV, Bloomberg Terminal)
79
+ - **Modular signal framework** with composable transformations and registry management
80
+ - **Deterministic backtesting** with transaction cost modeling and comprehensive metrics
81
+ - **Interactive visualization** with Plotly charts (equity curves, signals, drawdown)
82
+ - **File-based persistence** with metadata tracking and versioning
83
+ - **Strategy governance** with centralized registry and configuration management
84
+ - **Multi-format reporting** with console, markdown, and HTML output
85
+
86
+ ## Installation
87
+
88
+ ### From PyPI (Recommended)
89
+
90
+ ```bash
91
+ pip install aponyx
92
+ ```
93
+
94
+ **Optional dependencies:**
95
+
96
+ ```bash
97
+ # Visualization (Plotly)
98
+ pip install aponyx[viz]
99
+
100
+ # Bloomberg Terminal support (requires manual blpapi install)
101
+ pip install aponyx[bloomberg]
102
+
103
+ # Development tools
104
+ pip install aponyx[dev]
105
+ ```
106
+
107
+ ### From Source
108
+
109
+ Requires **Python 3.12** and [`uv`](https://docs.astral.sh/uv/):
110
+
111
+ ```bash
112
+ git clone https://github.com/stabilefrisur/aponyx.git
113
+ cd aponyx
114
+ uv sync # Install dependencies
115
+ uv sync --extra viz # Include visualization
116
+ ```
117
+
118
+ ### Bloomberg Terminal Setup (Optional)
119
+
120
+ > **Note:** Bloomberg data loading requires an active Terminal session and manual `blpapi` installation.
121
+
122
+ 1. Install `blpapi` by following the instructions here: [Bloomberg API Library](https://www.bloomberg.com/professional/support/api-library/)
123
+ 2. Install Bloomberg extra: `pip install aponyx[bloomberg]`
124
+
125
+ File-based data loading (`FileSource`) works without Bloomberg dependencies.
126
+
127
+ ## Quick Start
128
+
129
+ ### 1. Run Analysis
130
+
131
+ **Option A: Use CLI with YAML Config (Recommended)**
132
+
133
+ Create a workflow configuration file:
134
+
135
+ ```yaml
136
+ # workflow.yaml
137
+ label: my_test
138
+ signal: cdx_etf_basis
139
+ product: cdx_ig_5y
140
+ strategy: balanced
141
+ ```
142
+
143
+ Run the workflow:
144
+
145
+ ```bash
146
+ aponyx run workflow.yaml
147
+ # Or use example configs
148
+ aponyx run examples/workflow_minimal.yaml
149
+ ```
150
+
151
+ **Option B: Python API**
152
+
153
+ ```python
154
+ from aponyx.data import fetch_cdx, fetch_etf, FileSource
155
+ from aponyx.models import (
156
+ IndicatorTransformationRegistry, ScoreTransformationRegistry,
157
+ SignalTransformationRegistry, SignalRegistry, compose_signal
158
+ )
159
+ from aponyx.backtest import run_backtest, BacktestConfig
160
+ from aponyx.evaluation.performance import compute_all_metrics
161
+ from aponyx.evaluation.suitability import evaluate_signal_suitability, SuitabilityConfig
162
+ from aponyx.config import (
163
+ INDICATOR_TRANSFORMATION_PATH, SCORE_TRANSFORMATION_PATH,
164
+ SIGNAL_TRANSFORMATION_PATH, SIGNAL_CATALOG_PATH
165
+ )
166
+ from pathlib import Path
167
+
168
+ # Load validated market data
169
+ # FileSource uses registry.json for security-to-file mapping
170
+ source = FileSource(Path("data/raw/synthetic"))
171
+ cdx_df = fetch_cdx(source, security="cdx_ig_5y")
172
+ etf_df = fetch_etf(source, security="lqd")
173
+
174
+ # FOUR-STAGE SIGNAL COMPOSITION PIPELINE:
175
+ # Stage 1: Indicator Transformation - Raw metric from securities (bps, ratios)
176
+ # Stage 2: Score Transformation - Normalization (z-score, volatility adjustment)
177
+ # Stage 3: Signal Transformation - Trading rules (floor, cap, neutral_range)
178
+ # Stage 4: Position Calculation - Handled by backtest layer
179
+
180
+ # Load all four registries
181
+ indicator_registry = IndicatorTransformationRegistry(INDICATOR_TRANSFORMATION_PATH)
182
+ score_registry = ScoreTransformationRegistry(SCORE_TRANSFORMATION_PATH)
183
+ signal_trans_registry = SignalTransformationRegistry(SIGNAL_TRANSFORMATION_PATH)
184
+ signal_registry = SignalRegistry(SIGNAL_CATALOG_PATH)
185
+
186
+ # Compose signal via four-stage pipeline
187
+ market_data = {"cdx": cdx_df, "etf": etf_df}
188
+ result = compose_signal(
189
+ signal_name="cdx_etf_basis",
190
+ market_data=market_data,
191
+ indicator_registry=indicator_registry,
192
+ score_registry=score_registry,
193
+ signal_transformation_registry=signal_trans_registry,
194
+ signal_registry=signal_registry,
195
+ include_intermediates=True, # Optional: inspect intermediate stages
196
+ )
197
+ signal = result["signal"]
198
+ # result also contains: result["indicator"], result["score"] for debugging
199
+
200
+ # Evaluate signal-product suitability (optional pre-backtest assessment)
201
+ suitability_config = SuitabilityConfig(rolling_window=252) # ~1 year daily data
202
+ suitability = evaluate_signal_suitability(signal, cdx_df["spread"], suitability_config)
203
+ print(f"Suitability: {suitability.composite_score:.2f} ({suitability.decision})")
204
+
205
+ # Run backtest with transaction costs and risk management
206
+ backtest_config = BacktestConfig(
207
+ position_size_mm=10.0, # $10MM notional
208
+ sizing_mode="proportional", # Position scales with signal (default)
209
+ stop_loss_pct=5.0, # Exit if PnL falls 5% below entry value
210
+ take_profit_pct=10.0, # Exit if PnL rises 10% above entry value
211
+ transaction_cost_bps=1.0
212
+ )
213
+ results = run_backtest(signal, cdx_df["spread"], backtest_config)
214
+
215
+ # Compute comprehensive performance metrics
216
+ metrics = compute_all_metrics(results.pnl, results.positions)
217
+
218
+ # Analyze results
219
+ print(f"Sharpe Ratio: {metrics.sharpe_ratio:.2f}")
220
+ print(f"Total Return: ${metrics.total_return:,.0f}")
221
+ print(f"Win Rate: {metrics.hit_rate:.1%}")
222
+ ```
223
+
224
+ **Bloomberg Terminal alternative:**
225
+
226
+ ```python
227
+ from aponyx.data import BloombergSource
228
+ from pathlib import Path
229
+
230
+ # Both sources use identical interface
231
+ source = BloombergSource()
232
+ cdx_df = fetch_cdx(source, security="cdx_ig_5y")
233
+ ```
234
+
235
+ ## Command-Line Interface
236
+
237
+ Aponyx provides a **complete CLI orchestrator** for running research workflows from data loading through performance analysis.
238
+
239
+ **Get started:**
240
+
241
+ ```bash
242
+ aponyx --help # or aponyx -h
243
+ ```
244
+
245
+ ### Run Complete Workflow
246
+
247
+ All workflows are configured via YAML files. Create a config file with required fields:
248
+
249
+ **Minimal configuration** (`workflow.yaml`):
250
+ ```yaml
251
+ label: minimal_test
252
+ signal: spread_momentum
253
+ product: cdx_ig_5y
254
+ strategy: balanced
255
+ ```
256
+
257
+ **Complete configuration with all options**:
258
+ ```yaml
259
+ label: complete_test
260
+ signal: cdx_etf_basis
261
+ product: cdx_ig_5y
262
+ strategy: balanced
263
+
264
+ # Optional: Override any transformation stage
265
+ indicator: cdx_etf_spread_diff
266
+ score_transformation: z_score_20d
267
+ signal_transformation: bounded_1_5
268
+
269
+ # Optional: Override default securities
270
+ securities:
271
+ cdx: cdx_ig_5y
272
+ etf: lqd
273
+ data: synthetic
274
+ steps: [data, signal, suitability, backtest, performance, visualization]
275
+ force: true
276
+ ```
277
+
278
+ **Run workflows:**
279
+
280
+ ```bash
281
+ # Execute full 6-step workflow with minimal config
282
+ aponyx run workflow.yaml
283
+
284
+ # Use example configs
285
+ aponyx run examples/workflow_minimal.yaml
286
+ aponyx run examples/workflow_complete.yaml
287
+ ```
288
+
289
+ **Available YAML fields:**
290
+
291
+ | Field | Type | Required | Default | Description |
292
+ |-------|------|----------|---------|-------------|
293
+ | `label` | string | ✓ | - | Workflow label (lowercase letters, numbers, underscores; must start with letter) |
294
+ | `signal` | string | ✓ | - | Signal name from signal_catalog.json |
295
+ | `product` | string | ✓ | - | Product identifier (e.g., "cdx_ig_5y") |
296
+ | `strategy` | string | ✓ | - | Strategy name from strategy_catalog.json |
297
+ | `indicator` | string | | from signal | Override indicator transformation |
298
+ | `score_transformation` | string | | from signal | Override score transformation (normalization) |
299
+ | `signal_transformation` | string | | from signal | Override signal transformation (trading rules) |
300
+ | `securities` | dict | | from indicator | Custom security mapping |
301
+ | `data` | string | | "synthetic" | Data source (synthetic, file, bloomberg) |
302
+ | `steps` | list | | all | Specific steps to execute |
303
+ | `force` | boolean | | false | Force re-run (skip cache) |
304
+
305
+ ### Generate Reports
306
+
307
+ ```bash
308
+ # Console output with formatted tables (by label)
309
+ aponyx report --workflow minimal_test
310
+
311
+ # By numeric index (0 = most recent, ephemeral)
312
+ aponyx report --workflow 0
313
+
314
+ # Markdown file (default location: reports/)
315
+ aponyx report --workflow minimal_test --format markdown
316
+
317
+ # HTML file with styled formatting
318
+ aponyx report --workflow minimal_test --format html --output custom_report.html
319
+ ```
320
+
321
+ Reports aggregate suitability evaluation and performance analysis with comprehensive metrics and visualizations.
322
+
323
+ ### List Available Items
324
+
325
+ ```bash
326
+ aponyx list signals # View signal catalog
327
+ aponyx list strategies # View strategy catalog
328
+ aponyx list datasets # View data registry
329
+ aponyx list workflows # View workflow results (sorted by timestamp, newest first)
330
+ aponyx list workflows --label minimal_test # Filter workflows by label
331
+ ```
332
+
333
+ ### Clean Workflow Cache
334
+
335
+ ```bash
336
+ # Preview workflow cleanup
337
+ aponyx clean --workflows --all --dry-run
338
+
339
+ # Clean workflows older than 30 days
340
+ aponyx clean --workflows --older-than 30d
341
+
342
+ # Clean specific label's workflows
343
+ aponyx clean --workflows --label minimal_test --older-than 7d
344
+ ```
345
+
346
+ **Output format:**
347
+ ```
348
+ === Workflow Configuration ===
349
+ Label: minimal_test [config]
350
+ Product: cdx_ig_5y [config]
351
+ Signal: spread_momentum [config]
352
+ Indicator Transform: spread_momentum_5d [from signal]
353
+ Securities: cdx:cdx_ig_5y [from indicator]
354
+ Score Transform: volatility_adjust_20d [from signal]
355
+ Signal Transform: passthrough [from signal]
356
+ Strategy: balanced [config]
357
+ Data: synthetic [default]
358
+ Steps: all [default]
359
+ Force re-run: False [default]
360
+ ===============================
361
+
362
+ Completed 6 steps in 15.2s
363
+ Skipped 0 cached steps
364
+ Results: data/workflows/minimal_test_20251202_143230/
365
+ ```
366
+
367
+ **See [CLI Guide](https://github.com/stabilefrisur/aponyx/blob/master/src/aponyx/docs/cli_guide.md) for complete documentation and advanced usage.**
368
+
369
+ ## Architecture
370
+
371
+ Aponyx follows a **layered architecture** with clean separation of concerns:
372
+
373
+ | Layer | Purpose | Key Modules |
374
+ |-------|---------|-------------|
375
+ | **CLI** | Command-line orchestration and user interface | `aponyx run`, `aponyx report`, `aponyx list`, `aponyx clean` |
376
+ | **Workflows** | Pipeline orchestration with dependency tracking | `WorkflowEngine`, `WorkflowConfig`, `StepRegistry`, concrete steps |
377
+ | **Reporting** | Multi-format report generation | `generate_report`, console/markdown/HTML formatters |
378
+ | **Data** | Load, validate, transform market data | `fetch_cdx`, `fetch_vix`, `fetch_etf`, `apply_transform`, `FileSource`, `BloombergSource` |
379
+ | **Models** | Four-stage signal composition pipeline | `IndicatorTransformationRegistry`, `ScoreTransformationRegistry`, `SignalTransformationRegistry`, `compose_signal` |
380
+ | **Evaluation** | Pre-backtest screening (rolling window stability) and post-backtest analysis | `evaluate_signal_suitability`, `analyze_backtest_performance`, `PerformanceRegistry` |
381
+ | **Backtest** | Simulate execution and generate P&L | `run_backtest`, `BacktestConfig`, `StrategyRegistry` |
382
+ | **Visualization** | Interactive charts and dashboards | `plot_equity_curve`, `plot_signal`, `plot_drawdown` |
383
+ | **Persistence** | Save/load data with metadata registry | `save_parquet`, `load_parquet`, `DataRegistry` |
384
+
385
+ ### Data Storage
386
+
387
+ ```
388
+ data/
389
+ raw/ # Original source data (permanent)
390
+ bloomberg/ # Bloomberg Terminal downloads
391
+ registry.json # Security-to-file mapping
392
+ synthetic/ # Synthetic test data
393
+ registry.json # Security-to-file mapping
394
+ cache/ # Temporary performance cache (security-based naming: {security}_{hash}.parquet)
395
+ workflows/ # Timestamped workflow results ({label}_{timestamp}/)
396
+ .registries/ # Runtime metadata (not in git)
397
+ ```
398
+
399
+ ### Research Workflow
400
+
401
+ **CLI-Orchestrated Pipeline:**
402
+
403
+ ```
404
+ CLI Command (aponyx run)
405
+
406
+ Workflow Engine (dependency tracking + caching)
407
+
408
+ [Step 1] Data Layer (load, validate, transform)
409
+
410
+ [Step 2] Models Layer (indicator computation + signal composition)
411
+
412
+ [Step 3] Evaluation Layer (signal-product suitability)
413
+
414
+ [Step 4] Backtest Layer (execution simulation)
415
+
416
+ [Step 5] Evaluation Layer (performance metrics & analysis)
417
+
418
+ [Step 6] Visualization Layer (charts)
419
+
420
+ Reporting Layer (multi-format output)
421
+
422
+ Persistence Layer (results + metadata)
423
+ ```
424
+
425
+ ## Documentation
426
+
427
+ Documentation is **included with the package** and available after installation:
428
+
429
+ ```python
430
+ # Access docs programmatically
431
+ from aponyx.docs import get_docs_dir
432
+ docs_path = get_docs_dir()
433
+ print(docs_path) # Path to installed documentation
434
+ ```
435
+
436
+ ### Getting Started
437
+
438
+ | Document | Description |
439
+ |----------|-------------|
440
+ | [`cli_guide.md`](https://github.com/stabilefrisur/aponyx/blob/master/src/aponyx/docs/cli_guide.md) | Complete CLI orchestrator reference and advanced usage |
441
+ | [`cdx_overlay_strategy.md`](https://github.com/stabilefrisur/aponyx/blob/master/src/aponyx/docs/cdx_overlay_strategy.md) | Investment thesis and pilot signal implementations |
442
+
443
+ ### Research Workflow
444
+
445
+ | Document | Description |
446
+ |----------|-------------|
447
+ | [`signal_registry_usage.md`](https://github.com/stabilefrisur/aponyx/blob/master/src/aponyx/docs/signal_registry_usage.md) | Signal management and catalog workflow |
448
+ | [`signal_suitability_design.md`](https://github.com/stabilefrisur/aponyx/blob/master/src/aponyx/docs/signal_suitability_design.md) | Pre-backtest signal-product evaluation framework |
449
+ | [`performance_evaluation_design.md`](https://github.com/stabilefrisur/aponyx/blob/master/src/aponyx/docs/performance_evaluation_design.md) | Post-backtest performance analysis framework |
450
+
451
+ ### System Architecture
452
+
453
+ | Document | Description |
454
+ |----------|-------------|
455
+ | [`governance_design.md`](https://github.com/stabilefrisur/aponyx/blob/master/src/aponyx/docs/governance_design.md) | Registry, catalog, and config governance patterns |
456
+ | [`visualization_design.md`](https://github.com/stabilefrisur/aponyx/blob/master/src/aponyx/docs/visualization_design.md) | Chart architecture and Plotly/Streamlit patterns |
457
+ | [`logging_design.md`](https://github.com/stabilefrisur/aponyx/blob/master/src/aponyx/docs/logging_design.md) | Logging conventions and metadata tracking |
458
+
459
+ ### Development Reference
460
+
461
+ | Document | Description |
462
+ |----------|-------------|
463
+ | [`python_guidelines.md`](https://github.com/stabilefrisur/aponyx/blob/master/src/aponyx/docs/python_guidelines.md) | Code standards, type hints, and best practices |
464
+ | [`adding_data_providers.md`](https://github.com/stabilefrisur/aponyx/blob/master/src/aponyx/docs/adding_data_providers.md) | Data provider extension guide |
465
+
466
+ **All documentation** is included in the package and available on [GitHub](https://github.com/stabilefrisur/aponyx/tree/master/src/aponyx/docs).
467
+
468
+ ## What's Included
469
+
470
+ **Three pilot signals for CDX overlay strategies (via four-stage composition):**
471
+ 1. **CDX-ETF Basis** - Flow-driven mispricing from cash-derivative basis
472
+ 2. **CDX-VIX Gap** - Cross-asset risk sentiment divergence
473
+ 3. **Spread Momentum** - Short-term continuation in credit spreads
474
+
475
+ **Four-stage transformation pipeline:**
476
+ - Stage 1: Indicator Transformation (raw metric in interpretable units)
477
+ - Stage 2: Score Transformation (z-score, volatility adjustment)
478
+ - Stage 3: Signal Transformation (floor, cap, neutral range)
479
+ - Stage 4: Position Calculation (backtest layer)
480
+
481
+ **Core capabilities:** Type-safe data loading • Signal registry • Pre/post-backtest evaluation • Deterministic backtesting • Interactive visualizations
482
+
483
+ ## Development
484
+
485
+ ### Running Tests
486
+
487
+ ```bash
488
+ pytest # All tests
489
+ pytest --cov=aponyx # With coverage
490
+ pytest tests/models/ # Specific module
491
+ ```
492
+
493
+ ### Code Quality
494
+
495
+ ```bash
496
+ ruff format src/ tests/ # Format code
497
+ ruff check src/ tests/ # Lint
498
+ mypy src/ # Type check
499
+ ```
500
+
501
+ All tools are configured in `pyproject.toml` with project-specific settings.
502
+
503
+ ## Design Philosophy
504
+
505
+ ### Core Principles
506
+
507
+ 1. **Modularity** - Clean separation between data, models, backtest, and infrastructure
508
+ 2. **Reproducibility** - Deterministic outputs with seed control and metadata logging
509
+ 3. **Type Safety** - Strict type hints and runtime validation throughout
510
+ 4. **Simplicity** - Prefer functions over classes, explicit over implicit
511
+ 5. **Transparency** - Clear separation between strategy logic and execution
512
+ 6. **No Legacy Support** - Breaking changes without deprecation warnings; always use latest patterns
513
+
514
+ ### Signal Convention
515
+
516
+ All signals follow a **consistent sign convention** for interpretability:
517
+ - **Positive values** → Long credit risk (buy CDX = sell protection)
518
+ - **Negative values** → Short credit risk (sell CDX = buy protection)
519
+
520
+ This ensures clarity when evaluating signals independently or combining them in future research.
521
+
522
+ ## Requirements
523
+
524
+ - **Python 3.12** (no backward compatibility with 3.11 or earlier)
525
+ - Modern type syntax (`str | None`, not `Optional[str]`)
526
+ - Optional: Bloomberg Terminal with `blpapi` for live data
527
+
528
+ **Breaking changes:** This is an early-stage project under active development. Breaking changes may occur between versions without deprecation warnings or backward compatibility.
529
+
530
+ ## Contributing
531
+
532
+ This is an early-stage personal research project. See [CONTRIBUTING.md](CONTRIBUTING.md) for technical guidelines if you'd like to contribute.
533
+
534
+ ## Security
535
+
536
+ Security issues addressed on a best-effort basis. See [SECURITY.md](SECURITY.md) for reporting guidelines and scope.
537
+
538
+ ## License
539
+
540
+ MIT License - see [LICENSE](LICENSE) for details.
541
+
542
+ ## Links
543
+
544
+ - **PyPI**: https://pypi.org/project/aponyx/
545
+ - **Repository**: https://github.com/stabilefrisur/aponyx
546
+ - **Issues**: https://github.com/stabilefrisur/aponyx/issues
547
+ - **Changelog**: https://github.com/stabilefrisur/aponyx/blob/master/CHANGELOG.md
548
+
549
+ ---
550
+
551
+ **Maintained by stabilefrisur**
552
+ **Version**: 0.1.18 | **Last Updated**: December 14, 2025
@@ -0,0 +1,104 @@
1
+ aponyx/__init__.py,sha256=vWadVoWoxd8RrGrFvCVsepfuNLYF9Rooj7qRmwuER4k,326
2
+ aponyx/main.py,sha256=UffZb_df0IKaFFYlyU7Ey_Im8sMs5S8HkwqRDo9dN7w,127
3
+ aponyx/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ aponyx/backtest/__init__.py,sha256=gDhbbohIttXPj2naX7rTPnO4iJdA_0cc4VEEpFpA37s,979
5
+ aponyx/backtest/adapters.py,sha256=SCMKfpkXJTyamKOivgYhskX7aDMDE0daziqsqnT1ezw,2235
6
+ aponyx/backtest/config.py,sha256=OXfY6dndbzjJabPmlBLr_mPBjM58SrvSrb-Kh0zUi1c,3532
7
+ aponyx/backtest/engine.py,sha256=2pKo_-poq3BjBQuruNVD6GIAgi-5msIapuAichps5vU,21078
8
+ aponyx/backtest/protocols.py,sha256=vw3hhIyohQ0feF1GiYOKQp8JsQhNHZrnD291qmYPEM8,3017
9
+ aponyx/backtest/registry.py,sha256=1LdZwK0tJZLjwnl2LAsaq-w4hS-bpbnIiO_UWkB9w9g,11707
10
+ aponyx/backtest/strategy_catalog.json,sha256=XNsJCGqMAjPt2kJj8xSjyVXYSLNpgNr0j_bkTdFnIHc,1461
11
+ aponyx/cli/__init__.py,sha256=V5bxOQfz9PsbtpO66T-VxFgXecsQ61_j50CsG401xaI,114
12
+ aponyx/cli/main.py,sha256=GYnr8YmEdfZvvlr_kVZMIVeR0ewxkYUZ147FJXCUvoE,3401
13
+ aponyx/cli/commands/__init__.py,sha256=7_K_22ZC-O6jogkzgfp-IVl47ye6lHQJTvDhRVWpMWs,198
14
+ aponyx/cli/commands/clean.py,sha256=l6e4rHxqgxdmwjsbnQZ4KlvW9gq9-a4D8gXlHjHRPE4,10271
15
+ aponyx/cli/commands/list.py,sha256=iDjLcllppZgiYYiMueF1uiIRvix0micDRPf19Xo30CE,10855
16
+ aponyx/cli/commands/report.py,sha256=ZK-x0jOUy-FGT44yvwl5WwL5yf-9Q_yPBzVyWZOEjm8,4871
17
+ aponyx/cli/commands/run.py,sha256=39AZiB5xPFUZbYxoYIhTU8yqSGWTUkzNEhC_ePQMRCM,14862
18
+ aponyx/config/__init__.py,sha256=2hQMzjdZ_RgpadryrxkCFqg_W88NzTJhSnR7-BBnuHE,3175
19
+ aponyx/data/__init__.py,sha256=buaVjXLQAUC7xUspCl8RcMhStIFH_2IGpa4a50IuuVQ,2935
20
+ aponyx/data/bloomberg_config.py,sha256=Z8K6gwceUxWCxZm7KVYiP1yhSuV1cLDAHNfdLS9Jb0A,8525
21
+ aponyx/data/bloomberg_instruments.json,sha256=OICQhDaS8YtKjoGEuVDR6aLNYrnzHFkimVPCpErsoME,647
22
+ aponyx/data/bloomberg_securities.json,sha256=1-2Tn485cZT4EMFnIh8IIUbrtFiTGyBLXQCud-9pg3s,1278
23
+ aponyx/data/cache.py,sha256=8AEOZyv5OmrF1ST-0TBG_5pGPRATBoPTDni7H982kY4,7567
24
+ aponyx/data/fetch.py,sha256=bOujCT0Jlucp_AUGDvUTP2_oggv8rUe3iGK89CWHlFU,21939
25
+ aponyx/data/fetch_registry.py,sha256=OZ8rb3c95WZvLdui8QGRhSsyk6eOs8epoF-TIAQw-v4,3307
26
+ aponyx/data/loaders.py,sha256=Yi-hOegAaddvO3qs127tqyZGcRDwbopI1FPqO2DqyNg,6881
27
+ aponyx/data/registry.py,sha256=hGk2c4QcsMZEjMhtrqn3n_fcqVXMPBpE7n7oy57ch9E,15944
28
+ aponyx/data/requirements.py,sha256=WuGELAqi_r2LHct-Zv8eKgJ_vzCMxQWosisyd3bPUjg,3135
29
+ aponyx/data/sample_data.py,sha256=WQk-F7WVz6qvePjEYrL-aP8rk_Rt-4gkd2tVLNtYOJU,13239
30
+ aponyx/data/schemas.py,sha256=NnmNANiOdTqZfT1micfAMqz4XuM9T5T9KzmH0ai9sWY,1473
31
+ aponyx/data/sources.py,sha256=Wh_QbtLCu2lAeTN_7pjDnzaYWih0WRXatVS1qfwuWQc,4616
32
+ aponyx/data/synthetic_params.json,sha256=yYuGOYfEAxegraYkXPbzqdbfxyU2s2O4m7XOg0I9WL8,831
33
+ aponyx/data/transforms.py,sha256=o6KizzO1Nj1Qmvbb0zIjg-PNaPHKUeMsTO6B-hJ8Nts,10424
34
+ aponyx/data/validation.py,sha256=I8aFu-40vdOq00uGeKl7_eHYQ_z9hd9AUFjhvEB0uJ4,9750
35
+ aponyx/data/providers/__init__.py,sha256=OZBe9BwuVrFM-6gdZsIbIEGVVXWFNejoS5Vpk-t8qGY,302
36
+ aponyx/data/providers/bloomberg.py,sha256=KLCh_Lv0Vz3ESpXK4muQsepmlQyc8u0hPvTTLsS3K4Q,12456
37
+ aponyx/data/providers/file.py,sha256=-oMwCujrVp1xiJlqBQrlGdvxs8ukkd7yhcgigmdzj3A,3634
38
+ aponyx/docs/__init__.py,sha256=DASC2VaYusAmnY1kZ-EFN8O6gwsn_H8laMFLYcRZQnY,521
39
+ aponyx/docs/adding_data_providers.md,sha256=tasGOJOw7f-4JgoktJpl26Cytz_2qPx6-j8m8Xgv8uA,17883
40
+ aponyx/docs/cdx_knowledge_base.md,sha256=eOLDQ9wkpGm8nST2pJiUTYRr_K6sJ-CPKtiuMYNdJkg,12664
41
+ aponyx/docs/cdx_overlay_strategy.md,sha256=dP_jxjiBsuQwlLzMb6XaS0VEJe9iicp3Keddz5Uz8mo,6116
42
+ aponyx/docs/cli_guide.md,sha256=N7_06-_x_GzuB6rQJxISaVjYtsMZWlID0VCjWdQRhac,18730
43
+ aponyx/docs/governance_design.md,sha256=Ruj_fp1_61Kfq3zLuSpyPYAhHPJWlmSr7RA5-40BJRA,20252
44
+ aponyx/docs/logging_design.md,sha256=9YFssBCA47Fy-7aEGXjj62LBR0NTS5SljG5prMSoWvg,7922
45
+ aponyx/docs/performance_evaluation_design.md,sha256=4X7oespnknuLO-_Omsd4CaQ7vWbA3wuj2ontJUbdDw8,10059
46
+ aponyx/docs/python_guidelines.md,sha256=oiDBexPwecPtjjTN5_ulKFSPKUfM8WErqXItQc0elXg,21299
47
+ aponyx/docs/signal_registry_usage.md,sha256=1ETrZi3dmS8DKjiMlsKcy28ig3txXXsTnjHrqgVMbgs,10617
48
+ aponyx/docs/signal_suitability_design.md,sha256=ma-_CdMEaVlI52FMjdkrXp8nul9zqD8sUzuvfsCvm4A,17607
49
+ aponyx/docs/visualization_design.md,sha256=6uFth7FdBVGzN6Iae5PXZ2kQXRwpsBhoLvtLtX2ERy4,8426
50
+ aponyx/evaluation/__init__.py,sha256=bLPFhiCpnYBfyMipIxzZecSx_-M_gedXvxKdYos9uko,368
51
+ aponyx/evaluation/performance/__init__.py,sha256=U6JgCziMRNxuMCAC2_N0JcNTaW86GCrrVdlNF4rLshU,801
52
+ aponyx/evaluation/performance/adapters.py,sha256=zbmUb6ygDj9L1ia3F5lCP8bUQ4RhsrhlLkDvztEDqsw,3194
53
+ aponyx/evaluation/performance/analyzer.py,sha256=zDbuRJrnG0uKkEfI5jizray1RRD8obqv-7pW08a1jow,12060
54
+ aponyx/evaluation/performance/config.py,sha256=byJxcI6gCERj3cgsR7-Rw5QyrsTZS-nMK4H-DMowRtY,11001
55
+ aponyx/evaluation/performance/decomposition.py,sha256=OHGInGMWBLSgLnOLUnLSrhSWP-SFn7FGKm106DJ05oY,9375
56
+ aponyx/evaluation/performance/metrics.py,sha256=biEVaeAc9OAd_UQKcG2VUv4Fh4XydA4OcBeAnaJt3Sw,26018
57
+ aponyx/evaluation/performance/registry.py,sha256=w5Iy3QWx5PLpfEQ9_igy7INht3QT3UHE5KJKYdy_BmQ,10055
58
+ aponyx/evaluation/performance/report.py,sha256=WmdcZ-KdvmkTTfhNaaFxePek0Hl4w84YsNEaO8-250g,17350
59
+ aponyx/evaluation/suitability/__init__.py,sha256=ky3zBmmRZfJuSXqSafVDs-XQDextkXBZ4CJPChdnCqg,2216
60
+ aponyx/evaluation/suitability/config.py,sha256=Z6nHGdIWO5ZRrdTaWXyaXS7uYE6U9BXggC6qW8JNpbI,5310
61
+ aponyx/evaluation/suitability/evaluator.py,sha256=mYxAD-nF5pyxZqNI9yQyRxvb2vV5ysOe6JdDxuACGmA,12836
62
+ aponyx/evaluation/suitability/registry.py,sha256=DVVLTfMjZQ0rK6NVLKx0FkXTVlckaR_9AVFSoZFxDBI,10060
63
+ aponyx/evaluation/suitability/report.py,sha256=8V8TWrYkbje80joSTJqDqeNbxjh8y6H4TRfHnVScW7Q,12950
64
+ aponyx/evaluation/suitability/scoring.py,sha256=HAxdJl2oXTHq1YA7TLcq-duBPLXOdONGtz-LtIy_m08,9434
65
+ aponyx/evaluation/suitability/tests.py,sha256=tvkvHbbvM1HBPEMIR8aIygzYySnugxBeE1cceySANQU,8914
66
+ aponyx/examples/01_generate_synthetic_data.py,sha256=e8DSSpJ2v5jWY2M2ygqC443Ukq5q15QTJiS_GsJj3H4,1481
67
+ aponyx/examples/02_fetch_data_file.py,sha256=JU8lqYbtCPuTkhvGj8sGcEj7cQd0yeORUQoHHHdKxcQ,2436
68
+ aponyx/examples/03_fetch_data_bloomberg.py,sha256=DA4vPj-Zrh1K9drSSoMzaapfWzCuZH0u2AWQrQinsbQ,3165
69
+ aponyx/examples/04_compute_signal.py,sha256=cEYo4H9Pz3ypaj9_Jta6ONgE2i7PuUdt-VxCqsqFKJ0,5458
70
+ aponyx/examples/05_evaluate_suitability.py,sha256=UZLzKsNjK_Wld0ph8ykxlgBOe3I1FpVd5EB8znuJuBs,5928
71
+ aponyx/examples/06_run_backtest.py,sha256=75PtUNyx3M8PRw_5JKRwXMiwLf6UNaIzJp0vz2cEbyM,6488
72
+ aponyx/examples/07_analyze_performance.py,sha256=9Fjzv0CXeu-L06lFpFBt18RFioXIYnHUtS8sTz207mQ,6276
73
+ aponyx/examples/08_visualize_results.py,sha256=m3ai2glQ7rC1NapEqKCIaC7b-JFPxdNwnkg9nTNF7ww,6891
74
+ aponyx/models/__init__.py,sha256=XSxHGjO29fgiFbR5BatePzBmimllOzzNMzyV1EGHLqs,1562
75
+ aponyx/models/config.py,sha256=_t75jJtIvABu0fseo_KgJE1yw52j0VIfgY3t80yUaHQ,2584
76
+ aponyx/models/indicator_transformation.json,sha256=cUGDhevOG30ZiYq642mxk0o2RW5kL0VkSRYBTMvs7eU,1402
77
+ aponyx/models/indicators.py,sha256=JAn10ftbKAwJHSHlliO9F9w3nKjW6PumxDp3lI1synk,9019
78
+ aponyx/models/metadata.py,sha256=9D_tzntb4TLKjd7qW0rcu83jo3ncHNzX6vDeeDesaBA,17129
79
+ aponyx/models/orchestrator.py,sha256=SW0ieopIs1ZEGsWsiQ8hnQCidptT1I1INnFOj4vWvvE,7285
80
+ aponyx/models/registry.py,sha256=SgEqFGsNjkOt-W0jLOMt1BBo8YX4TRWCObqLCZs7a74,29202
81
+ aponyx/models/score_transformation.json,sha256=ws80pfFB794ADeED_UNEuShw69bfVsRO21WjiV0Yjq0,1015
82
+ aponyx/models/signal_catalog.json,sha256=rTq-FjBikVBKR8GdbG9d9JjmIH56BicN1uFra1xUtJs,981
83
+ aponyx/models/signal_composer.py,sha256=QWNYMJ65jCZgyhT-cTy83DZjkzZjOg1s956N9iiI0h8,19112
84
+ aponyx/models/signal_transformation.json,sha256=vuI5RkHMIp_2AEfYVZ5kjFWycJKarV68jGLf1PVmJK4,688
85
+ aponyx/persistence/__init__.py,sha256=-IuzHVRO0hbbB7WagmZI3vhmS69Tuzx3gYDf3AhFs98,372
86
+ aponyx/persistence/json_io.py,sha256=53g5nSyXlYXHFv5dUMUZevEbl3RywK3tnf0bvXelo9U,3559
87
+ aponyx/persistence/parquet_io.py,sha256=YM2cxNsi5KCbIa4Se3YgIv03xc42XTSjRyZiebNzrf0,10833
88
+ aponyx/reporting/__init__.py,sha256=uOVjZLeiL4RAaQavsBb4Cym9sXLThZ3Urq_WJjDO6ec,289
89
+ aponyx/reporting/generator.py,sha256=zB7C8YLXl4dG9ejF64WVVdKSo1aqeZzfz-II4xuC9JQ,17255
90
+ aponyx/visualization/__init__.py,sha256=06clVGN2HGwuocqzBbMNSFuSNJn1_oEQ1trmKtd4JfA,462
91
+ aponyx/visualization/app.py,sha256=Oocv4IY5xrZJxmPSMgK5neV1iLHVr1tK4MMqZrPmJVo,913
92
+ aponyx/visualization/plots.py,sha256=yHIs3kjKe8Sw_MVdpb1Wq-hkZEqyTKoiNaDNt5DKAck,8587
93
+ aponyx/visualization/visualizer.py,sha256=ad5mg0UF_ocpOpCbYgtFWZ9NmZiejbOTfaA8v-jXIWc,6518
94
+ aponyx/workflows/__init__.py,sha256=HIwjvLjLP926Q5ia60s7aB864_kgsb21aoJCrRcDYgA,448
95
+ aponyx/workflows/concrete_steps.py,sha256=XgyrGMF_oMWbTtb4BiHvnascwc0ojRYo7SygWaLM468,26726
96
+ aponyx/workflows/config.py,sha256=yJukQXTMXZgcAhnGXrwJI2_3HoTZylaSfZuddHB23Mg,4883
97
+ aponyx/workflows/engine.py,sha256=tk4QO53TJEP8bI_mJ9t0EbDe0Bv01hWbtnqJZHb3rEg,8985
98
+ aponyx/workflows/registry.py,sha256=zT0cdjjnTfpffK3i4sjn8wIt0tod0pAzeXHENmnEnpU,3074
99
+ aponyx/workflows/steps.py,sha256=53RW1P4rywW7Xxv4Rsnazl5qUaa2x-w7AOcpw1s2SOs,4507
100
+ aponyx-0.1.18.dist-info/METADATA,sha256=ckwjW54XG9PChFl3jE2p20WM1CPcpSVaSLnXJutK1ZE,21374
101
+ aponyx-0.1.18.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
102
+ aponyx-0.1.18.dist-info/entry_points.txt,sha256=Qr-Mhv1RwWQVg4M9eV1qbNqMwimnidy1c78Ku5plXQM,48
103
+ aponyx-0.1.18.dist-info/licenses/LICENSE,sha256=NkbMWtm3EOnGAoFvIyZUoSDQFQd-g51U3q74JYJGmWs,1092
104
+ aponyx-0.1.18.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ aponyx = aponyx.cli.main:main