sagan-trade 0.2.4__tar.gz

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 (67) hide show
  1. sagan_trade-0.2.4/CHANGELOG.md +60 -0
  2. sagan_trade-0.2.4/LICENSE +21 -0
  3. sagan_trade-0.2.4/MANIFEST.in +10 -0
  4. sagan_trade-0.2.4/PKG-INFO +171 -0
  5. sagan_trade-0.2.4/README.md +102 -0
  6. sagan_trade-0.2.4/docs/api/cli.md +78 -0
  7. sagan_trade-0.2.4/docs/api/config.md +73 -0
  8. sagan_trade-0.2.4/docs/api/data.md +52 -0
  9. sagan_trade-0.2.4/docs/api/ensemble.md +16 -0
  10. sagan_trade-0.2.4/docs/api/exceptions.md +77 -0
  11. sagan_trade-0.2.4/docs/api/index.md +55 -0
  12. sagan_trade-0.2.4/docs/api/logging.md +44 -0
  13. sagan_trade-0.2.4/docs/api/predict.md +39 -0
  14. sagan_trade-0.2.4/docs/api/registry.md +84 -0
  15. sagan_trade-0.2.4/docs/api/utils.md +59 -0
  16. sagan_trade-0.2.4/docs/architecture.md +226 -0
  17. sagan_trade-0.2.4/docs/changelog.md +34 -0
  18. sagan_trade-0.2.4/docs/contributing.md +116 -0
  19. sagan_trade-0.2.4/docs/getting-started.md +146 -0
  20. sagan_trade-0.2.4/docs/index.md +153 -0
  21. sagan_trade-0.2.4/docs/tutorials/custom_config.md +142 -0
  22. sagan_trade-0.2.4/docs/tutorials/parallel_training.md +133 -0
  23. sagan_trade-0.2.4/docs/tutorials/single_stock.md +133 -0
  24. sagan_trade-0.2.4/pyproject.toml +128 -0
  25. sagan_trade-0.2.4/requirements.txt +5 -0
  26. sagan_trade-0.2.4/sagan/__init__.py +86 -0
  27. sagan_trade-0.2.4/sagan/__main__.py +6 -0
  28. sagan_trade-0.2.4/sagan/app.py +291 -0
  29. sagan_trade-0.2.4/sagan/cli/auth.py +86 -0
  30. sagan_trade-0.2.4/sagan/cli/commands.py +137 -0
  31. sagan_trade-0.2.4/sagan/compliance/report.py +72 -0
  32. sagan_trade-0.2.4/sagan/config.py +73 -0
  33. sagan_trade-0.2.4/sagan/data.py +234 -0
  34. sagan_trade-0.2.4/sagan/database.py +60 -0
  35. sagan_trade-0.2.4/sagan/ensemble.py +112 -0
  36. sagan_trade-0.2.4/sagan/exceptions.py +100 -0
  37. sagan_trade-0.2.4/sagan/explain/formatter.py +39 -0
  38. sagan_trade-0.2.4/sagan/explain/gemma.py +63 -0
  39. sagan_trade-0.2.4/sagan/indicators.py +46 -0
  40. sagan_trade-0.2.4/sagan/logging_config.py +81 -0
  41. sagan_trade-0.2.4/sagan/metrics.py +151 -0
  42. sagan_trade-0.2.4/sagan/models/__init__.py +1 -0
  43. sagan_trade-0.2.4/sagan/models/llm_bridge.py +77 -0
  44. sagan_trade-0.2.4/sagan/models/manager.py +86 -0
  45. sagan_trade-0.2.4/sagan/models/math_engine.py +104 -0
  46. sagan_trade-0.2.4/sagan/models/pinn_loss.py +23 -0
  47. sagan_trade-0.2.4/sagan/models/tft.py +105 -0
  48. sagan_trade-0.2.4/sagan/models/xai_layer.py +38 -0
  49. sagan_trade-0.2.4/sagan/parallel.py +192 -0
  50. sagan_trade-0.2.4/sagan/portfolio/csv_import.py +29 -0
  51. sagan_trade-0.2.4/sagan/portfolio/snaptrade.py +18 -0
  52. sagan_trade-0.2.4/sagan/predict.py +112 -0
  53. sagan_trade-0.2.4/sagan/py.typed +1 -0
  54. sagan_trade-0.2.4/sagan/registry.py +259 -0
  55. sagan_trade-0.2.4/sagan/signals.py +51 -0
  56. sagan_trade-0.2.4/sagan/utils.py +152 -0
  57. sagan_trade-0.2.4/sagan_trade.egg-info/PKG-INFO +171 -0
  58. sagan_trade-0.2.4/sagan_trade.egg-info/SOURCES.txt +65 -0
  59. sagan_trade-0.2.4/sagan_trade.egg-info/dependency_links.txt +1 -0
  60. sagan_trade-0.2.4/sagan_trade.egg-info/entry_points.txt +2 -0
  61. sagan_trade-0.2.4/sagan_trade.egg-info/requires.txt +36 -0
  62. sagan_trade-0.2.4/sagan_trade.egg-info/top_level.txt +1 -0
  63. sagan_trade-0.2.4/setup.cfg +4 -0
  64. sagan_trade-0.2.4/setup.py +44 -0
  65. sagan_trade-0.2.4/tests/test_data.py +51 -0
  66. sagan_trade-0.2.4/tests/test_ensemble.py +54 -0
  67. sagan_trade-0.2.4/tests/test_utils.py +84 -0
@@ -0,0 +1,60 @@
1
+ # Changelog
2
+
3
+ All notable changes to **Sagan XAI** will be documented here.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ---
9
+
10
+ ## [0.2.1] – 2026-04-15
11
+
12
+ ### Fixed
13
+ - Dashboard SyntaxError: Fixed `nonlocal` scoping issue in `sagan/app.py` that occurred when using certain Python versions or execution contexts.
14
+
15
+ ## [0.2.0] – 2026-04-15
16
+
17
+ ### Added
18
+ - SEBI Compliance Engine: Dual export of signals to `.md` and `.json`.
19
+ - Automated Threshold Optimization: Model-generated RSI and Volatility boundaries for 2000+ NSE stocks.
20
+ - HITL Audit Logic: Local SQLite database (`sagan.db`) recording all actions and model justifications.
21
+ - Gating-Driven Conflict resolution: Using TFT Variable Selection Network (VSN) weights to manage signal discrepancies.
22
+ - Consolidated Typer CLI: New commands `userlogs`, `metrics`, and `dash`.
23
+
24
+ ## [0.0.1] – 2026-04-15
25
+
26
+ ### Changed
27
+ - **Completely removed paywall and credit tracking**: Firestore-based billing and tiered feature gating have been stripped. The library is now fully open and free.
28
+ - **Fixed TensorFlow retracing issue**: Optimized prediction pipeline to use direct model calls and added an LRU cache for model loading, resolving expensive tracing warnings during inference.
29
+ - **Reset versioning**: Reset package version to `0.0.1` as per state transition.
30
+
31
+ ### Removed
32
+ - `sagan.billing` module and all related Firestore/sync logic.
33
+ - `auth`, `sync`, and `usage` CLI commands.
34
+ - Dependencies: `authlib`, `python-jose`, `httpx`.
35
+
36
+ ---
37
+
38
+ ## [0.1.0] – 2024-04-11
39
+
40
+ ### Added
41
+ - **`ExplainableEnsemble`** – three-head TFT model (buy / sell / hold) with PINN mean-reversion loss.
42
+ - **`train()`** – convenience wrapper that fetches, trains, and registers an ensemble in one call.
43
+ - **`predict()`** – generates a `LONG / SHORT / NEUTRAL` signal with confidence and XAI override flag.
44
+ - **`batch_predict()`** – compares signals across multiple saved model IDs.
45
+ - **`train_parallel()`** / **`train_parallel_from_fetch()`** – multiprocessing dispatch for training one model per ticker simultaneously.
46
+ - **`list_models()`** / **`delete_model()`** / **`export_model()`** – full registry lifecycle management.
47
+ - **`SaganConfig`** – centralised configuration dataclass with `from_env()` and `from_dict()` factory methods.
48
+ - **`setup_logging()`** – configurable logger helper.
49
+ - **`sharpe_ratio()`**, **`max_drawdown()`**, **`annualised_return()`**, **`calmar_ratio()`** – reusable financial metrics.
50
+ - **Custom exception hierarchy**: `SaganError`, `ModelNotFoundError`, `InsufficientDataError`, `FetchError`, `ConfigurationError`, `RegistryCorruptedError`.
51
+ - **CLI** (`sagan --train`, `--predict`, `--list`, `--parallel`, `--model-id`, `--epochs`, `--window`, `--horizon`).
52
+ - **Full MkDocs Material documentation** hosted at <https://sagan-docs.vercel.app>.
53
+ - **GitHub Actions** CI (lint + type-check + test) and PyPI publish workflows.
54
+ - `py.typed` marker for PEP 561 compliance.
55
+
56
+ ### Notes
57
+ - Initial public alpha. API may evolve before `1.0.0`.
58
+ - TensorFlow ≥ 2.10 required; GPU is auto-detected but not required.
59
+
60
+ [0.1.0]: https://github.com/sagan-labs/sagan/releases/tag/v0.1.0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Sagan Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,10 @@
1
+ include README.md
2
+ include LICENSE
3
+ include CHANGELOG.md
4
+ include pyproject.toml
5
+ include requirements.txt
6
+ recursive-include sagan *.py py.typed
7
+ recursive-include docs *.md *.yml *.png *.svg
8
+ recursive-exclude * __pycache__
9
+ recursive-exclude * *.pyc
10
+ recursive-exclude * *.pyo
@@ -0,0 +1,171 @@
1
+ Metadata-Version: 2.4
2
+ Name: sagan-trade
3
+ Version: 0.2.4
4
+ Summary: Strategic Symbolic Trading Engine with iterative R2 fitting and FunctionGemma discovery.
5
+ Home-page: https://github.com/sagan-labs/sagan-xai
6
+ Author: Sagan Labs
7
+ Author-email: Sagan Labs <hello@sagan-docs.vercel.app>
8
+ License: MIT
9
+ Project-URL: Homepage, https://sagan-trade.vercel.app
10
+ Project-URL: Documentation, https://sagan-trade.vercel.app
11
+ Project-URL: Source, https://github.com/That-Tech-Geek/sagan-trade
12
+ Project-URL: Bug Tracker, https://github.com/That-Tech-Geek/sagan-trade/issues
13
+ Project-URL: Changelog, https://sagan-trade.vercel.app/changelog
14
+ Project-URL: PyPI, https://pypi.org/project/sagan-trade/
15
+ Keywords: trading,quantitative-finance,machine-learning,explainable-ai,pinn,temporal-fusion-transformer,mean-reversion,ensemble,deep-learning
16
+ Classifier: Development Status :: 3 - Alpha
17
+ Classifier: Intended Audience :: Financial and Insurance Industry
18
+ Classifier: Intended Audience :: Science/Research
19
+ Classifier: Topic :: Office/Business :: Financial :: Investment
20
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
21
+ Classifier: Programming Language :: Python :: 3
22
+ Classifier: Programming Language :: Python :: 3.9
23
+ Classifier: Programming Language :: Python :: 3.10
24
+ Classifier: Programming Language :: Python :: 3.11
25
+ Classifier: Programming Language :: Python :: 3.12
26
+ Classifier: License :: OSI Approved :: MIT License
27
+ Classifier: Operating System :: OS Independent
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.8
30
+ Description-Content-Type: text/markdown
31
+ License-File: LICENSE
32
+ Requires-Dist: tensorflow>=2.10
33
+ Requires-Dist: pandas>=1.5
34
+ Requires-Dist: numpy>=1.23
35
+ Requires-Dist: yfinance>=0.2
36
+ Requires-Dist: scikit-learn>=1.1
37
+ Requires-Dist: streamlit>=1.25
38
+ Requires-Dist: plotly>=5.15
39
+ Requires-Dist: cryptography
40
+ Requires-Dist: typer
41
+ Requires-Dist: snaptrade-python-sdk
42
+ Requires-Dist: schedule
43
+ Provides-Extra: dev
44
+ Requires-Dist: pytest>=7.4; extra == "dev"
45
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
46
+ Requires-Dist: ruff>=0.4; extra == "dev"
47
+ Requires-Dist: mypy>=1.5; extra == "dev"
48
+ Requires-Dist: build>=1.0; extra == "dev"
49
+ Requires-Dist: twine>=4.0; extra == "dev"
50
+ Requires-Dist: mkdocs-material>=9.5; extra == "dev"
51
+ Requires-Dist: mkdocstrings[python]>=0.24; extra == "dev"
52
+ Provides-Extra: ci
53
+ Requires-Dist: pytest>=7.4; extra == "ci"
54
+ Requires-Dist: pytest-cov>=4.0; extra == "ci"
55
+ Requires-Dist: ruff>=0.4; extra == "ci"
56
+ Requires-Dist: mypy>=1.5; extra == "ci"
57
+ Requires-Dist: pandas>=1.5; extra == "ci"
58
+ Requires-Dist: numpy>=1.23; extra == "ci"
59
+ Requires-Dist: scikit-learn>=1.1; extra == "ci"
60
+ Requires-Dist: yfinance>=0.2; extra == "ci"
61
+ Provides-Extra: docs
62
+ Requires-Dist: mkdocs-material>=9.5; extra == "docs"
63
+ Requires-Dist: mkdocstrings[python]>=0.24; extra == "docs"
64
+ Requires-Dist: mkdocs-git-revision-date-localized-plugin>=1.2; extra == "docs"
65
+ Dynamic: author
66
+ Dynamic: home-page
67
+ Dynamic: license-file
68
+ Dynamic: requires-python
69
+
70
+ # Sagan Trade
71
+
72
+ > **High-throughput symbolic mathematical trading engine**
73
+
74
+ [![Python](https://img.shields.io/badge/python-3.9%2B-blue)](https://python.org)
75
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
76
+ [![PyPI](https://img.shields.io/pypi/v/sagan-trade.svg)](https://pypi.org/project/sagan-trade/)
77
+
78
+ Sagan Trade replaces black-box neural networks with transparent, human-readable mathematical equations discovered via **FunctionGemma** (via Ollama).
79
+
80
+ | Component | Role |
81
+ |---|---|
82
+ | **Symbolic Regressor** | Fits variables to R2 > 0.95 using Polynomial and Fourier basis functions. |
83
+ | **FunctionGemma** | AI architect that suggests optimal mathematical compositions of signals. |
84
+ | **Power Hub** | OS-level optimization for maximum throughput (Eco, Balanced, Turbo). |
85
+
86
+ ---
87
+
88
+ ## Installation
89
+
90
+ ```bash
91
+ pip install sagan-trade
92
+ ```
93
+
94
+ Or in editable mode from source:
95
+
96
+ ```bash
97
+ git clone https://github.com/That-Tech-Geek/sagan-trade
98
+ cd sagan-trade
99
+ pip install -e ".[dev]"
100
+ ```
101
+
102
+ ---
103
+
104
+ ## Quick Start
105
+
106
+ ### Python API
107
+
108
+ ```python
109
+ import sagan
110
+
111
+ # Train a symbolic ensemble with high-accuracy math fitting
112
+ model_id = sagan.train(
113
+ ["AAPL"],
114
+ signals=["Close", "Volume", "RSI"],
115
+ target_r2=0.95,
116
+ profile="turbo"
117
+ )
118
+
119
+ # Predict using the latest symbolic expression
120
+ result = sagan.predict()
121
+ print(result["signal"]) # "LONG" | "SHORT"
122
+ print(result["formula"]) # e.g. "(Close * 0.5) + log(Volume)"
123
+ ```
124
+
125
+ ### Command-Line Interface
126
+
127
+ ```bash
128
+ # List available math signals for a ticker
129
+ sagan vars AAPL
130
+
131
+ # Train symbolic model
132
+ sagan train AAPL --signals Close,Volume --r2 0.95 --profile turbo
133
+
134
+ # Get Trading Signal
135
+ sagan predict
136
+ ```
137
+
138
+ ---
139
+
140
+ ## Architecture
141
+
142
+ ```
143
+ yfinance Data
144
+
145
+
146
+ [Parallel Fitting] → Each variable fitted to R2 > 0.95
147
+
148
+
149
+ [FunctionGemma] → Suggests composite math formula
150
+
151
+
152
+ [Evaluation] → Trend-based signal generation
153
+ ```
154
+
155
+ ---
156
+
157
+ ## Configuration
158
+
159
+ All defaults live in `sagan.config`:
160
+
161
+ ```python
162
+ from sagan import config
163
+
164
+ config.models_dir = "~/.sagan/models/"
165
+ ```
166
+
167
+ ---
168
+
169
+ ## License
170
+
171
+ [MIT](LICENSE) © 2024 Sagan Labs
@@ -0,0 +1,102 @@
1
+ # Sagan Trade
2
+
3
+ > **High-throughput symbolic mathematical trading engine**
4
+
5
+ [![Python](https://img.shields.io/badge/python-3.9%2B-blue)](https://python.org)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
+ [![PyPI](https://img.shields.io/pypi/v/sagan-trade.svg)](https://pypi.org/project/sagan-trade/)
8
+
9
+ Sagan Trade replaces black-box neural networks with transparent, human-readable mathematical equations discovered via **FunctionGemma** (via Ollama).
10
+
11
+ | Component | Role |
12
+ |---|---|
13
+ | **Symbolic Regressor** | Fits variables to R2 > 0.95 using Polynomial and Fourier basis functions. |
14
+ | **FunctionGemma** | AI architect that suggests optimal mathematical compositions of signals. |
15
+ | **Power Hub** | OS-level optimization for maximum throughput (Eco, Balanced, Turbo). |
16
+
17
+ ---
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ pip install sagan-trade
23
+ ```
24
+
25
+ Or in editable mode from source:
26
+
27
+ ```bash
28
+ git clone https://github.com/That-Tech-Geek/sagan-trade
29
+ cd sagan-trade
30
+ pip install -e ".[dev]"
31
+ ```
32
+
33
+ ---
34
+
35
+ ## Quick Start
36
+
37
+ ### Python API
38
+
39
+ ```python
40
+ import sagan
41
+
42
+ # Train a symbolic ensemble with high-accuracy math fitting
43
+ model_id = sagan.train(
44
+ ["AAPL"],
45
+ signals=["Close", "Volume", "RSI"],
46
+ target_r2=0.95,
47
+ profile="turbo"
48
+ )
49
+
50
+ # Predict using the latest symbolic expression
51
+ result = sagan.predict()
52
+ print(result["signal"]) # "LONG" | "SHORT"
53
+ print(result["formula"]) # e.g. "(Close * 0.5) + log(Volume)"
54
+ ```
55
+
56
+ ### Command-Line Interface
57
+
58
+ ```bash
59
+ # List available math signals for a ticker
60
+ sagan vars AAPL
61
+
62
+ # Train symbolic model
63
+ sagan train AAPL --signals Close,Volume --r2 0.95 --profile turbo
64
+
65
+ # Get Trading Signal
66
+ sagan predict
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Architecture
72
+
73
+ ```
74
+ yfinance Data
75
+
76
+
77
+ [Parallel Fitting] → Each variable fitted to R2 > 0.95
78
+
79
+
80
+ [FunctionGemma] → Suggests composite math formula
81
+
82
+
83
+ [Evaluation] → Trend-based signal generation
84
+ ```
85
+
86
+ ---
87
+
88
+ ## Configuration
89
+
90
+ All defaults live in `sagan.config`:
91
+
92
+ ```python
93
+ from sagan import config
94
+
95
+ config.models_dir = "~/.sagan/models/"
96
+ ```
97
+
98
+ ---
99
+
100
+ ## License
101
+
102
+ [MIT](LICENSE) © 2024 Sagan Labs
@@ -0,0 +1,78 @@
1
+ # CLI Reference
2
+
3
+ The `sagan` command-line tool is installed automatically with the package.
4
+
5
+ ```bash
6
+ sagan --help
7
+ ```
8
+
9
+ ---
10
+
11
+ ## Commands
12
+
13
+ ### `--train`
14
+
15
+ Train a new ensemble on one or more tickers.
16
+
17
+ ```bash
18
+ sagan --train RELIANCE.NS TCS.NS HDFCBANK.NS
19
+ ```
20
+
21
+ | Flag | Type | Default | Description |
22
+ |---|---|---|---|
23
+ | `--train TICKERS…` | `str+` | — | **Required.** Ticker symbols |
24
+ | `--years INT` | int | 5 | Years of historical data |
25
+ | `--window INT` | int | 10 | Look-back window (days) |
26
+ | `--horizon INT` | int | 3 | Forward horizon for labelling |
27
+ | `--epochs INT` | int | 30 | Max training epochs |
28
+ | `--parallel` | flag | off | Train one model per ticker in parallel |
29
+ | `--num-processes INT` | int | 12 | Parallel worker processes |
30
+
31
+ ---
32
+
33
+ ### `--predict`
34
+
35
+ Generate a trading signal using the latest (or a specific) saved model.
36
+
37
+ ```bash
38
+ sagan --predict
39
+ sagan --predict --model-id sagan_20240411_120000_abc123
40
+ ```
41
+
42
+ | Flag | Type | Default | Description |
43
+ |---|---|---|---|
44
+ | `--predict` | flag | — | **Required.** Activate predict mode |
45
+ | `--model-id STR` | str | latest | Specific model to query |
46
+
47
+ ---
48
+
49
+ ### `--list`
50
+
51
+ Display a table of all registered models.
52
+
53
+ ```bash
54
+ sagan --list
55
+ ```
56
+
57
+ Output columns: `model_id`, `tickers`, `val_sharpe`, `override_fraction`, `created_at`.
58
+
59
+ ---
60
+
61
+ ## Examples
62
+
63
+ ```bash
64
+ # Train on NSE blue-chips, 5 years
65
+ sagan --train RELIANCE.NS TCS.NS INFY.NS HDFCBANK.NS --years 5
66
+
67
+ # Parallel training on US tech (8 workers)
68
+ sagan --train AAPL MSFT GOOGL AMZN META --parallel --num-processes 8
69
+
70
+ # Aggressive hyper-params
71
+ sagan --train AAPL --window 20 --horizon 5 --epochs 100
72
+
73
+ # Predict with a specific model
74
+ sagan --predict --model-id sagan_20240411_120000_abc123
75
+
76
+ # List all models
77
+ sagan --list
78
+ ```
@@ -0,0 +1,73 @@
1
+ # Config
2
+
3
+ The `sagan.config` module exposes the :class:`~sagan.config.SaganConfig` dataclass
4
+ and the module-level `config` singleton that all Sagan modules share.
5
+
6
+ ---
7
+
8
+ ## SaganConfig
9
+
10
+ ::: sagan.config.SaganConfig
11
+
12
+ ---
13
+
14
+ ## config (singleton)
15
+
16
+ ```python
17
+ from sagan import config
18
+
19
+ # Inspect defaults
20
+ print(config.default_window) # 10
21
+ print(config.xai_confidence_threshold) # 0.6
22
+ print(config.models_dir) # ~/.sagan/xai_models
23
+
24
+ # Mutate for the current session
25
+ config.default_epochs = 50
26
+ config.pinn_lambda = 0.005
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Environment Variables
32
+
33
+ `SaganConfig.from_env()` reads the following variables:
34
+
35
+ | Variable | Field | Type |
36
+ |---|---|---|
37
+ | `SAGAN_HOME_DIR` | `home_dir` | `Path` |
38
+ | `SAGAN_MODELS_DIR` | `models_dir` | `Path` |
39
+ | `SAGAN_DEFAULT_WINDOW` | `default_window` | `int` |
40
+ | `SAGAN_DEFAULT_HORIZON` | `default_horizon` | `int` |
41
+ | `SAGAN_DEFAULT_EPOCHS` | `default_epochs` | `int` |
42
+ | `SAGAN_DEFAULT_HEAD_DIM` | `default_head_dim` | `int` |
43
+ | `SAGAN_DEFAULT_NUM_HEADS` | `default_num_heads` | `int` |
44
+ | `SAGAN_DEFAULT_FF_DIM` | `default_ff_dim` | `int` |
45
+ | `SAGAN_DEFAULT_DROPOUT` | `default_dropout` | `float` |
46
+ | `SAGAN_DEFAULT_THRESHOLD` | `default_threshold` | `float` |
47
+ | `SAGAN_PINN_LAMBDA` | `pinn_lambda` | `float` |
48
+ | `SAGAN_XAI_CONFIDENCE_THRESHOLD` | `xai_confidence_threshold` | `float` |
49
+ | `SAGAN_REGIME_CHANGE_THRESHOLD` | `regime_change_threshold` | `float` |
50
+
51
+ ---
52
+
53
+ ## Example: Programmatic override
54
+
55
+ ```python
56
+ from sagan.config import SaganConfig
57
+ import sagan
58
+
59
+ # Override via dict
60
+ cfg = SaganConfig.from_dict({
61
+ "default_window": 20,
62
+ "default_epochs": 50,
63
+ "pinn_lambda": 0.005,
64
+ })
65
+
66
+ # Use with ExplainableEnsemble
67
+ from sagan import ExplainableEnsemble
68
+ ens = ExplainableEnsemble(
69
+ ["AAPL"],
70
+ window=cfg.default_window,
71
+ epochs=cfg.default_epochs,
72
+ )
73
+ ```
@@ -0,0 +1,52 @@
1
+ # Data
2
+
3
+ The `sagan.data` module handles price data acquisition and supervised dataset preparation.
4
+
5
+ ---
6
+
7
+ ## fetch_prices
8
+
9
+ ::: sagan.data.fetch_prices
10
+
11
+ ---
12
+
13
+ ## validate_tickers
14
+
15
+ ::: sagan.data.validate_tickers
16
+
17
+ ---
18
+
19
+ ## prepare_probabilistic_data
20
+
21
+ ::: sagan.data.prepare_probabilistic_data
22
+
23
+ ---
24
+
25
+ ## Labelling scheme
26
+
27
+ Given a forward return $\bar{r}$ and a threshold $\delta$:
28
+
29
+ | Condition | Label | Class index |
30
+ |---|---|---|
31
+ | $\bar{r} > \delta$ | **BUY** | 0 |
32
+ | $\bar{r} < -\delta$ | **SELL** | 1 |
33
+ | $-\delta \le \bar{r} \le \delta$ | **HOLD** | 2 |
34
+
35
+ The one-hot label vector `y_probs[i]` has shape `(3,)` and sums to 1.
36
+
37
+ ---
38
+
39
+ ## Example: Manual data preparation
40
+
41
+ ```python
42
+ from sagan.data import fetch_prices, prepare_probabilistic_data
43
+
44
+ prices = fetch_prices(["RELIANCE.NS", "TCS.NS"], years=3)
45
+ X, y_probs, y_ret, symbols, n_stocks = prepare_probabilistic_data(
46
+ prices, window=10, horizon=3, threshold=0.01
47
+ )
48
+
49
+ print(X.shape) # (N, 10, 2)
50
+ print(y_probs.shape) # (N, 3)
51
+ print(symbols) # ['RELIANCE.NS', 'TCS.NS']
52
+ ```
@@ -0,0 +1,16 @@
1
+ # Ensemble
2
+
3
+ The `sagan.ensemble` module contains the :class:`~sagan.ensemble.ExplainableEnsemble`
4
+ class and the :func:`~sagan.ensemble.train` convenience function.
5
+
6
+ ---
7
+
8
+ ## ExplainableEnsemble
9
+
10
+ ::: sagan.ensemble.ExplainableEnsemble
11
+
12
+ ---
13
+
14
+ ## train
15
+
16
+ ::: sagan.ensemble.train
@@ -0,0 +1,77 @@
1
+ # Exceptions
2
+
3
+ All Sagan exceptions inherit from :class:`~sagan.exceptions.SaganError`,
4
+ allowing callers to catch any library error with a single `except SaganError`.
5
+
6
+ ---
7
+
8
+ ## Hierarchy
9
+
10
+ ```
11
+ SaganError
12
+ ├── ModelNotFoundError
13
+ ├── InsufficientDataError
14
+ ├── FetchError
15
+ ├── ConfigurationError
16
+ └── RegistryCorruptedError
17
+ ```
18
+
19
+ ---
20
+
21
+ ## SaganError
22
+
23
+ ::: sagan.exceptions.SaganError
24
+
25
+ ---
26
+
27
+ ## ModelNotFoundError
28
+
29
+ ::: sagan.exceptions.ModelNotFoundError
30
+
31
+ ---
32
+
33
+ ## InsufficientDataError
34
+
35
+ ::: sagan.exceptions.InsufficientDataError
36
+
37
+ ---
38
+
39
+ ## FetchError
40
+
41
+ ::: sagan.exceptions.FetchError
42
+
43
+ ---
44
+
45
+ ## ConfigurationError
46
+
47
+ ::: sagan.exceptions.ConfigurationError
48
+
49
+ ---
50
+
51
+ ## RegistryCorruptedError
52
+
53
+ ::: sagan.exceptions.RegistryCorruptedError
54
+
55
+ ---
56
+
57
+ ## Catching exceptions
58
+
59
+ ```python
60
+ from sagan.exceptions import (
61
+ SaganError,
62
+ ModelNotFoundError,
63
+ FetchError,
64
+ InsufficientDataError,
65
+ )
66
+ import sagan
67
+
68
+ # Catch all Sagan errors
69
+ try:
70
+ result = sagan.predict(model_id="bad_id")
71
+ except ModelNotFoundError as exc:
72
+ print(f"Model '{exc.model_id}' doesn't exist")
73
+ except FetchError as exc:
74
+ print(f"Data fetch failed for {exc.tickers}")
75
+ except SaganError as exc:
76
+ print(f"Sagan error: {exc}")
77
+ ```