propalgos 0.1.0__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 (61) hide show
  1. propalgos-0.1.0/.gitignore +222 -0
  2. propalgos-0.1.0/LICENSE +29 -0
  3. propalgos-0.1.0/PKG-INFO +437 -0
  4. propalgos-0.1.0/README.md +392 -0
  5. propalgos-0.1.0/examples/quickstart.py +24 -0
  6. propalgos-0.1.0/pyproject.toml +73 -0
  7. propalgos-0.1.0/src/propalgos/__init__.py +70 -0
  8. propalgos-0.1.0/src/propalgos/_version.py +1 -0
  9. propalgos-0.1.0/src/propalgos/account/__init__.py +10 -0
  10. propalgos-0.1.0/src/propalgos/api/__init__.py +11 -0
  11. propalgos-0.1.0/src/propalgos/auth/__init__.py +11 -0
  12. propalgos-0.1.0/src/propalgos/backtest/__init__.py +22 -0
  13. propalgos-0.1.0/src/propalgos/backtest/costs.py +43 -0
  14. propalgos-0.1.0/src/propalgos/backtest/engine.py +263 -0
  15. propalgos-0.1.0/src/propalgos/backtest/metrics.py +77 -0
  16. propalgos-0.1.0/src/propalgos/backtest/results.py +132 -0
  17. propalgos-0.1.0/src/propalgos/cli/__init__.py +5 -0
  18. propalgos-0.1.0/src/propalgos/cli/main.py +84 -0
  19. propalgos-0.1.0/src/propalgos/config.py +59 -0
  20. propalgos-0.1.0/src/propalgos/data/__init__.py +37 -0
  21. propalgos-0.1.0/src/propalgos/data/cache.py +145 -0
  22. propalgos-0.1.0/src/propalgos/data/crypto.py +353 -0
  23. propalgos-0.1.0/src/propalgos/data/loader.py +166 -0
  24. propalgos-0.1.0/src/propalgos/data/prices.py +312 -0
  25. propalgos-0.1.0/src/propalgos/data/registry.py +186 -0
  26. propalgos-0.1.0/src/propalgos/data/returns.py +134 -0
  27. propalgos-0.1.0/src/propalgos/data/schemas.py +45 -0
  28. propalgos-0.1.0/src/propalgos/data/staging.py +42 -0
  29. propalgos-0.1.0/src/propalgos/env/__init__.py +131 -0
  30. propalgos-0.1.0/src/propalgos/env/gpu.py +296 -0
  31. propalgos-0.1.0/src/propalgos/env/runtime.py +83 -0
  32. propalgos-0.1.0/src/propalgos/exceptions.py +75 -0
  33. propalgos-0.1.0/src/propalgos/factors/__init__.py +56 -0
  34. propalgos-0.1.0/src/propalgos/factors/performance.py +155 -0
  35. propalgos-0.1.0/src/propalgos/factors/risk.py +163 -0
  36. propalgos-0.1.0/src/propalgos/notebook/__init__.py +10 -0
  37. propalgos-0.1.0/src/propalgos/py.typed +0 -0
  38. propalgos-0.1.0/src/propalgos/signals/__init__.py +38 -0
  39. propalgos-0.1.0/src/propalgos/signals/compose.py +93 -0
  40. propalgos-0.1.0/src/propalgos/signals/mean_reversion.py +107 -0
  41. propalgos-0.1.0/src/propalgos/signals/momentum.py +131 -0
  42. propalgos-0.1.0/src/propalgos/signals/scan.py +139 -0
  43. propalgos-0.1.0/src/propalgos/signals/trend.py +137 -0
  44. propalgos-0.1.0/src/propalgos/storage/__init__.py +11 -0
  45. propalgos-0.1.0/src/propalgos/submit/__init__.py +10 -0
  46. propalgos-0.1.0/src/propalgos/viz/__init__.py +63 -0
  47. propalgos-0.1.0/src/propalgos/viz/_compat.py +41 -0
  48. propalgos-0.1.0/src/propalgos/viz/candles.py +266 -0
  49. propalgos-0.1.0/src/propalgos/viz/heatmaps.py +216 -0
  50. propalgos-0.1.0/src/propalgos/viz/strip.py +139 -0
  51. propalgos-0.1.0/src/propalgos/viz/tearsheet.py +359 -0
  52. propalgos-0.1.0/src/propalgos/viz/theme.py +186 -0
  53. propalgos-0.1.0/tests/__init__.py +0 -0
  54. propalgos-0.1.0/tests/conftest.py +42 -0
  55. propalgos-0.1.0/tests/test_backtest.py +114 -0
  56. propalgos-0.1.0/tests/test_data.py +453 -0
  57. propalgos-0.1.0/tests/test_factors.py +124 -0
  58. propalgos-0.1.0/tests/test_import.py +134 -0
  59. propalgos-0.1.0/tests/test_signals.py +265 -0
  60. propalgos-0.1.0/tests/test_viz.py +284 -0
  61. propalgos-0.1.0/uv.lock +3097 -0
@@ -0,0 +1,222 @@
1
+ # Environment variables
2
+ .env
3
+ .env.local
4
+ .env.development.local
5
+ .env.test.local
6
+ .env.production.local
7
+ frontend/.env
8
+ backend/.env
9
+ backend/.env.bak
10
+ backend/.env.backup
11
+ backend/.env.vault
12
+ cloud_api_testing/config/.env
13
+ temp/
14
+ temp/*
15
+
16
+ # Cloud credentials
17
+ cloud_creds/
18
+ cloud_creds/*
19
+
20
+ # Vault init keys (NEVER commit)
21
+ .vault-init-keys.json
22
+
23
+ # Dependencies
24
+ node_modules/
25
+ */node_modules/
26
+
27
+ # Build outputs (frontend only)
28
+ frontend/build/
29
+ frontend/dist/
30
+
31
+ # Runtime data
32
+ pids
33
+ *.pid
34
+ *.seed
35
+ *.pid.lock
36
+
37
+ # Coverage directory used by tools like istanbul
38
+ coverage/
39
+ *.lcov
40
+
41
+ # Python coverage files
42
+ backend/htmlcov/
43
+ backend/.coverage
44
+ backend/coverage.xml
45
+ backend/*.coverage.*
46
+ # Keep the baseline coverage json
47
+ !backend/coverage.json
48
+ !backend/test_coverage_baseline.json
49
+
50
+ # nyc test coverage
51
+ .nyc_output
52
+
53
+ # ESLint cache
54
+ .eslintcache
55
+
56
+ # Optional npm cache directory
57
+ .npm
58
+
59
+ # Optional REPL history
60
+ .node_repl_history
61
+
62
+ # Output of 'npm pack'
63
+ *.tgz
64
+
65
+ # Yarn Integrity file
66
+ .yarn-integrity
67
+
68
+ # parcel-bundler cache (https://parceljs.org/)
69
+ .cache
70
+ .parcel-cache
71
+
72
+ # next.js build output
73
+ .next
74
+
75
+ # nuxt.js build output
76
+ .nuxt
77
+
78
+ # vuepress build output
79
+ .vuepress/dist
80
+
81
+ # Serverless directories
82
+ .serverless
83
+
84
+ # FuseBox cache
85
+ .fusebox/
86
+
87
+ # DynamoDB Local files
88
+ .dynamodb/
89
+
90
+ # TernJS port file
91
+ .tern-port
92
+
93
+ # IDE files
94
+ .vscode/
95
+ .idea/
96
+ *.swp
97
+ *.swo
98
+ *~
99
+
100
+ # OS generated files
101
+ .DS_Store
102
+ .DS_Store?
103
+ ._*
104
+ .Spotlight-V100
105
+ .Trashes
106
+ ehthumbs.db
107
+ Thumbs.db
108
+
109
+ # Logs
110
+ logs
111
+ *.log
112
+ npm-debug.log*
113
+ yarn-debug.log*
114
+ yarn-error.log*
115
+ lerna-debug.log*
116
+
117
+ # Python
118
+ __pycache__/
119
+ *.py[cod]
120
+ *$py.class
121
+ *.so
122
+ .Python
123
+ /env/
124
+ venv/
125
+ /ENV/
126
+ env.bak/
127
+ venv.bak/
128
+ backend/waitlist-env/
129
+ backend/*-env/
130
+
131
+ # uv specific
132
+ .venv/
133
+ backend/.venv/
134
+ uv.lock.*
135
+ .uv/
136
+ backend/.uv/
137
+
138
+ # Jupyter Notebook
139
+ .ipynb_checkpoints
140
+
141
+ # pyenv
142
+ .python-version
143
+
144
+ # AWS
145
+ .aws/
146
+ docker/aws/credentials
147
+ docker/aws/credentials.backup
148
+
149
+ # Terraform
150
+ *.tfstate
151
+ *.tfstate.*
152
+ .terraform/
153
+ .terraform.lock.hcl
154
+
155
+ # Docker
156
+ #.dockerignore
157
+
158
+ # Miscellaneous
159
+ archive/
160
+ archive/*
161
+ CURRENT_TODO/
162
+ backend/.env_COPY
163
+
164
+ # Vault credentials (local development only)
165
+ .vault-credentials
166
+ **/.vault-credentials
167
+ vault-backup.json.gpg
168
+
169
+ # Vault backups (contain sensitive data)
170
+ vault-complete-backup*.json
171
+ vault-backup*.json
172
+ *.vault-backup.json
173
+
174
+ # Packer build artifacts (3.8GB on 2025-10-12!)
175
+ backend/packer_build_logs/*.log
176
+ backend/packer_build_logs/*.json
177
+ backend/packer_build_logs/
178
+ infrastructure/packer/templates/manifest.json
179
+ infrastructure/packer/scripts/userdata/
180
+
181
+ # Image scanner reports
182
+ backend/services/image_scanners/
183
+ infrastructure/ssm_documents/
184
+
185
+ # Memory/context files (not committed)
186
+ docs/memory/
187
+
188
+ # Temporary test files
189
+ backend/test_*.py
190
+ !backend/tests/
191
+ infrastructure/test_*.py
192
+ infrastructure/tests/
193
+ backend/tmp*.json
194
+ backend/*.tmp
195
+
196
+ # Cloud API testing cache
197
+ cloud_api_testing/scripts/gcp_gpu_api.py
198
+ docker/aws/cli/cache/
199
+
200
+ # Integration test artifacts
201
+ frontend/*_TESTS.md
202
+ frontend/**/*.integration.md
203
+
204
+ # Backup files
205
+ **/*.bak
206
+ **/*.bak2
207
+ backups/
208
+
209
+ # Test result artifacts
210
+ **/*_test_results.json
211
+ **/*_FINDINGS.md
212
+ backend/test_gpu.db
213
+ backend/test_gpu_performance.db
214
+
215
+ # Azure setup files (planning docs)
216
+ AZURE_SETUP_FILES/
217
+
218
+ # Crypto data cache (bootstrap/refresh artifacts)
219
+ infrastructure/scripts/crypto_cache/
220
+
221
+ # Database dumps
222
+ propalgos_backup.dump
@@ -0,0 +1,29 @@
1
+ Copyright (c) 2026 PropAlgos, Inc. All rights reserved.
2
+
3
+ PROPRIETARY SOFTWARE LICENSE
4
+
5
+ This software and associated documentation files (the "Software") are the
6
+ proprietary property of PropAlgos, Inc. ("PropAlgos").
7
+
8
+ Permission is hereby granted to any person who has obtained a copy of this
9
+ Software through an authorized distribution channel (PyPI, PropAlgos platform,
10
+ or direct download from PropAlgos) to use the Software for personal and
11
+ commercial purposes, subject to the following conditions:
12
+
13
+ 1. You may NOT redistribute, sublicense, sell, or otherwise transfer copies
14
+ of the Software to third parties without prior written permission from
15
+ PropAlgos.
16
+
17
+ 2. You may NOT modify, reverse engineer, decompile, or disassemble the
18
+ Software except to the extent that such activity is expressly permitted
19
+ by applicable law.
20
+
21
+ 3. You may NOT remove or alter any proprietary notices, labels, or marks
22
+ on the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27
+ PROPALGOS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,437 @@
1
+ Metadata-Version: 2.4
2
+ Name: propalgos
3
+ Version: 0.1.0
4
+ Summary: Quant research SDK for PropAlgos — data, signals, backtesting, and visualization
5
+ Project-URL: Homepage, https://propalgos.ai
6
+ Project-URL: Documentation, https://propalgos.ai/docs
7
+ Author-email: PropAlgos <eng@propalgos.ai>
8
+ License: Proprietary
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Financial and Insurance Industry
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: License :: Other/Proprietary License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Office/Business :: Financial :: Investment
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: httpx>=0.28
23
+ Requires-Dist: numpy>=1.26
24
+ Requires-Dist: pandas>=2.2
25
+ Requires-Dist: pydantic>=2.8
26
+ Requires-Dist: typer[all]>=0.15
27
+ Requires-Dist: yfinance>=0.2.40
28
+ Provides-Extra: dev
29
+ Requires-Dist: build>=1.2; extra == 'dev'
30
+ Requires-Dist: ipywidgets>=8.1; extra == 'dev'
31
+ Requires-Dist: mypy>=1.15; extra == 'dev'
32
+ Requires-Dist: plotly>=6.0; extra == 'dev'
33
+ Requires-Dist: pyarrow>=18.0; extra == 'dev'
34
+ Requires-Dist: pytest>=8.3; extra == 'dev'
35
+ Requires-Dist: ruff>=0.11; extra == 'dev'
36
+ Provides-Extra: keyring
37
+ Requires-Dist: keyring>=25.0; extra == 'keyring'
38
+ Provides-Extra: notebook
39
+ Requires-Dist: ipykernel>=6.29; extra == 'notebook'
40
+ Requires-Dist: jupyterlab>=4.2; extra == 'notebook'
41
+ Provides-Extra: viz
42
+ Requires-Dist: ipywidgets>=8.1; extra == 'viz'
43
+ Requires-Dist: plotly>=6.0; extra == 'viz'
44
+ Description-Content-Type: text/markdown
45
+
46
+ # propalgos
47
+
48
+ Quant research SDK for [PropAlgos](https://propalgos.ai) — data, signals, backtesting, and visualization on GPU cloud instances.
49
+
50
+ ## Install
51
+
52
+ ```bash
53
+ pip install propalgos
54
+
55
+ # with visualization (plotly)
56
+ pip install 'propalgos[viz]'
57
+
58
+ # with notebook support (jupyterlab)
59
+ pip install 'propalgos[notebook]'
60
+
61
+ # all optional deps
62
+ pip install 'propalgos[viz,notebook,keyring]'
63
+
64
+ # development
65
+ pip install -e ".[dev,viz]"
66
+ ```
67
+
68
+ Or with uv:
69
+
70
+ ```bash
71
+ uv add propalgos
72
+ uv add 'propalgos[viz]'
73
+ ```
74
+
75
+ ## Quickstart
76
+
77
+ ```python
78
+ import propalgos as pa
79
+
80
+ prices = pa.data.prices("SPY", start="2020-01-01")
81
+ signal = pa.signals.sma_cross(prices, fast=20, slow=100)
82
+ bt = pa.backtest.run(prices, signal, initial_cash=100_000, fee_bps=1)
83
+ bt.summary()
84
+ pa.viz.tearsheet(bt)
85
+ ```
86
+
87
+ ## CLI
88
+
89
+ ```bash
90
+ propalgos version # print SDK version
91
+ propalgos doctor # check deps and connectivity
92
+ propalgos env # print runtime environment summary (GPU, frameworks, cloud)
93
+ propalgos --help # all commands
94
+ ```
95
+
96
+ The `pa` alias works too: `pa version`, `pa doctor`, `pa env`.
97
+
98
+ ---
99
+
100
+ ## Module Reference
101
+
102
+ ### `pa.data` — Market Data
103
+
104
+ ```python
105
+ # fetch OHLCV data (yfinance backend, disk-cached)
106
+ prices = pa.data.prices("SPY", start="2020-01-01", end="2024-12-31", interval="1d")
107
+
108
+ # multiple symbols → MultiIndex columns
109
+ prices = pa.data.prices(["SPY", "QQQ"], start="2023-01-01")
110
+
111
+ # returns
112
+ daily = pa.data.returns(prices) # simple returns
113
+ log_r = pa.data.returns(prices, method="log") # log returns
114
+ cum = pa.data.cumulative_returns(daily) # cumulative
115
+
116
+ # load from file
117
+ prices = pa.data.from_csv("my_data.csv")
118
+
119
+ # bulk dataset loading (on-platform or with local parquets)
120
+ df = pa.data.load("crypto-kraken", interval="1h") # stacked multi-symbol DataFrame
121
+ datasets = pa.data.list_datasets() # discover available datasets
122
+ symbols = pa.data.list_symbols("crypto-kraken", interval="1d") # symbols in a dataset
123
+
124
+ # swap data backend
125
+ from propalgos.data.prices import DataProvider
126
+ pa.data.configure(my_custom_provider) # must implement DataProvider protocol
127
+ pa.data.clear_cache() # purge disk cache
128
+ ```
129
+
130
+ | Function | Parameters | Returns |
131
+ |----------|-----------|---------|
132
+ | `prices` | `symbols`, `start=None`, `end=None`, `interval="1d"`, `cache=True` | `pd.DataFrame` |
133
+ | `returns` | `prices_df`, `method="simple"` | `pd.DataFrame` |
134
+ | `cumulative_returns` | `returns_df` | `pd.DataFrame` |
135
+ | `from_csv` | `path` | `pd.DataFrame` |
136
+ | `load` | `dataset_id`, `interval="1d"` | `pd.DataFrame` |
137
+ | `list_datasets` | — | `list[dict]` |
138
+ | `list_symbols` | `dataset_id`, `interval="1d"` | `list[str]` |
139
+ | `configure` | `provider: DataProvider` | `None` |
140
+ | `clear_cache` | — | `int` (files removed) |
141
+
142
+ **DataProvider protocol** — implement `name: str` property and `fetch_prices(symbols, start, end, interval) -> pd.DataFrame`.
143
+
144
+ ---
145
+
146
+ ### `pa.signals` — Signal Generators
147
+
148
+ All signal functions accept a `pd.DataFrame` with a `close` column and return a `pd.Series` of `{-1, 0, 1}` (sell, flat, buy). Warmup periods output `0`.
149
+
150
+ ```python
151
+ sig = pa.signals.sma_cross(prices, fast=20, slow=100)
152
+ sig = pa.signals.rsi_reversion(prices, period=14, overbought=70, oversold=30)
153
+ sig = pa.signals.combine([sig_a, sig_b], method="and")
154
+
155
+ # raw RSI values (0-100 float, not a signal)
156
+ rsi_values = pa.signals.rsi(prices, period=14)
157
+
158
+ # multi-symbol operations (stacked DataFrames)
159
+ df = pa.signals.rsi_stacked(stacked_df, period=14, symbol_col="symbol") # adds 'rsi' column
160
+ df = pa.signals.scan(stacked_df, pa.signals.sma_cross, symbol_col="symbol") # adds 'signal' column
161
+ ```
162
+
163
+ | Function | Parameters | Strategy |
164
+ |----------|-----------|----------|
165
+ | `sma_cross` | `fast=20`, `slow=100` | SMA crossover — long when fast > slow |
166
+ | `ema_cross` | `fast=12`, `slow=26` | EMA crossover |
167
+ | `trend_filter` | `period=50` | Trend following — long above SMA, short below |
168
+ | `rsi_reversion` | `period=14`, `overbought=70`, `oversold=30` | RSI mean reversion |
169
+ | `rsi` | `period=14` | Raw RSI values (0–100 float, not a signal) |
170
+ | `macd` | *(default MACD params)* | MACD histogram sign |
171
+ | `bollinger_bands` | `period=20`, `num_std=2.0` | Band extremes — long at lower, short at upper |
172
+ | `zscore_reversion` | `period=20`, `entry_z=2.0`, `exit_z=0.5` | Z-score extremes |
173
+ | `combine` | `signals: list`, `method="and"\|"or"\|"majority"` | Combine multiple signals |
174
+ | `rsi_stacked` | `df`, `period=14`, `symbol_col="symbol"` | Vectorized RSI across stacked multi-symbol DataFrames |
175
+ | `scan` | `df`, `signal_fn`, `symbol_col="symbol"` | Generic groupby applicator — apply any signal function across symbols |
176
+
177
+ ---
178
+
179
+ ### `pa.factors` — Performance Metrics & Risk Analytics
180
+
181
+ All functions accept a `pd.Series` of daily simple returns.
182
+
183
+ ```python
184
+ pa.factors.sharpe(returns) # 1.42
185
+ pa.factors.max_drawdown(returns) # 0.187
186
+ pa.factors.var(returns, 0.95) # 0.023
187
+ ```
188
+
189
+ **Performance** (annualized where applicable):
190
+
191
+ | Function | Parameters | Returns |
192
+ |----------|-----------|---------|
193
+ | `sharpe` | `rf=0.0` | `float` |
194
+ | `sortino` | `rf=0.0` | `float` |
195
+ | `calmar` | — | `float` |
196
+ | `total_return` | — | `float` |
197
+ | `annualized_return` | — | `float` |
198
+ | `annualized_volatility` | — | `float` |
199
+ | `win_rate` | — | `float` |
200
+ | `profit_factor` | — | `float` |
201
+
202
+ **Risk:**
203
+
204
+ | Function | Parameters | Returns |
205
+ |----------|-----------|---------|
206
+ | `var` | `confidence=0.95` | `float` |
207
+ | `cvar` | `confidence=0.95` | `float` |
208
+ | `max_drawdown` | — | `float` |
209
+ | `drawdown_series` | — | `pd.Series` |
210
+ | `beta` | `strategy_returns, benchmark_returns` | `float` |
211
+ | `rolling_volatility` | `window=20` | `pd.Series` |
212
+
213
+ **Constant:** `pa.factors.TRADING_DAYS = 252`
214
+
215
+ ---
216
+
217
+ ### `pa.backtest` — Vectorized Backtesting
218
+
219
+ ```python
220
+ result = pa.backtest.run(
221
+ prices, # DataFrame with 'close' column
222
+ signal, # Series of {-1, 0, 1}
223
+ initial_cash=100_000, # starting capital
224
+ fee_bps=5, # 0.05% per trade
225
+ slippage_bps=2, # 0.02% slippage
226
+ benchmark="SPY", # optional benchmark (str or DataFrame)
227
+ )
228
+
229
+ result.summary() # formatted text output
230
+ result.to_dict() # serializable dict
231
+ result.to_json() # JSON string
232
+ ```
233
+
234
+ **BacktestResult attributes:**
235
+
236
+ | Attribute | Type | Description |
237
+ |-----------|------|-------------|
238
+ | `equity_curve` | `pd.Series` | Dollar equity by date |
239
+ | `returns` | `pd.Series` | Daily simple returns |
240
+ | `positions` | `pd.Series` | Position at each bar (-1, 0, 1) |
241
+ | `trades` | `pd.DataFrame` | One row per position change |
242
+ | `drawdowns` | `pd.Series` | Peak-to-trough drawdown series |
243
+ | `benchmark_equity` | `pd.Series \| None` | Benchmark equity curve |
244
+ | `benchmark_returns` | `pd.Series \| None` | Benchmark daily returns |
245
+ | `metrics` | `dict[str, float]` | Sharpe, Sortino, max DD, CAGR, etc. |
246
+ | `initial_cash` | `float` | Starting capital |
247
+ | `cost_model` | `CostModel` | Fee + slippage config |
248
+
249
+ **CostModel:** `CostModel(fee_bps=0, slippage_bps=0)` — immutable cost config.
250
+
251
+ ---
252
+
253
+ ### `pa.viz` — Visualization
254
+
255
+ Requires `plotly` — install with `pip install 'propalgos[viz]'`.
256
+
257
+ ```python
258
+ pa.viz.tearsheet(result) # multi-panel backtest tearsheet
259
+ pa.viz.candles(prices, indicators=["sma20", "bb20"], signals=signal)
260
+ pa.viz.monthly_returns(result) # years x months heatmap
261
+ pa.viz.heatmap(matrix, colorscale="rsi", fmt=".0f", zrange=(0, 100))
262
+ pa.viz.strip(data, x="timeframe", y="rsi", color="symbol",
263
+ thresholds={"Oversold": (0, 30), "Overbought": (70, 100)})
264
+ ```
265
+
266
+ | Function | Description |
267
+ |----------|-------------|
268
+ | `tearsheet(result)` | Equity curve + drawdown + monthly returns + metrics panel. Auto-shows in notebooks. |
269
+ | `candles(prices, indicators=None, signals=None, title=None)` | Candlestick chart with optional SMA/EMA/BB overlays and buy/sell markers. |
270
+ | `monthly_returns(result_or_returns)` | Monthly returns heatmap (years x months). Accepts BacktestResult or raw Series. |
271
+ | `heatmap(z, colorscale="diverging", fmt=".1%", title="", zrange=None)` | General-purpose heatmap for any DataFrame matrix. |
272
+ | `strip(data, x, y, color, thresholds=None, title="", y_range=None)` | Strip/jitter plot with optional threshold bands for signal distribution. |
273
+
274
+ **Indicator specs** for `candles()`: `sma{n}`, `ema{n}`, `bb{n}` (e.g. `"sma20"`, `"ema50"`, `"bb20"`).
275
+
276
+ **Colorscale presets**: `"diverging"` (red → green), `"sequential"` (green → red), `"rsi"` (green → red, 5-stop). Or pass a raw Plotly colorscale list.
277
+
278
+ #### Dark/Light Mode
279
+
280
+ ```python
281
+ pa.viz.set_mode("light") # switch to light theme
282
+ pa.viz.tearsheet(result) # now renders with light palette
283
+
284
+ pa.viz.set_mode("dark") # back to default dark theme
285
+ ```
286
+
287
+ All chart functions read from the active palette automatically. `COLORS` dict and `COLORSCALES` dict update in place when mode changes.
288
+
289
+ | Function/Object | Description |
290
+ |-----------------|-------------|
291
+ | `set_mode("dark" \| "light")` | Set global theme mode |
292
+ | `colors()` | Returns active color palette dict |
293
+ | `colorscales()` | Returns active colorscale presets dict |
294
+ | `COLORS` | Active palette dict (mutates with `set_mode`) |
295
+ | `COLORSCALES` | Active colorscale presets (mutates with `set_mode`) |
296
+ | `apply_theme(fig)` | Apply PropAlgos theme to any Plotly figure |
297
+
298
+ ---
299
+
300
+ ### `pa.env` — Environment Detection
301
+
302
+ ```python
303
+ pa.env.summary()
304
+ # PropAlgos Environment
305
+ # ─────────────────────
306
+ # Runtime: PropAlgos Cloud (AWS us-east-1, g4dn.xlarge)
307
+ # Python: 3.11.9
308
+ # GPU: NVIDIA T4 (16 GB) — CUDA 12.4
309
+ # Frameworks: PyTorch 2.3.0 (GPU), RAPIDS cuDF 24.10 (GPU)
310
+
311
+ gpu = pa.env.gpu() # GPUInfo(available=True, name="NVIDIA T4", ...)
312
+ fws = pa.env.frameworks() # [FrameworkInfo(name="torch", version="2.3.0", gpu_enabled=True), ...]
313
+ rt = pa.env.detect_runtime() # RuntimeInfo(on_propalgos=True, cloud_provider="aws", ...)
314
+ ```
315
+
316
+ | Function | Returns | Description |
317
+ |----------|---------|-------------|
318
+ | `summary()` | `None` | Print formatted environment info to stdout |
319
+ | `gpu()` | `GPUInfo` | GPU hardware detection (nvidia-smi → torch → tensorflow fallback) |
320
+ | `in_propalgos()` | `bool` | True if running on a PropAlgos-managed instance |
321
+ | `frameworks()` | `list[FrameworkInfo]` | Detected ML frameworks (torch, tensorflow, jax, RAPIDS) |
322
+ | `detect_runtime()` | `RuntimeInfo` | Cloud provider, region, instance type, Python version |
323
+
324
+ **GPUInfo fields**: `available`, `name`, `memory_mb`, `driver_version`, `cuda_version`, `count`
325
+
326
+ **RuntimeInfo fields**: `on_propalgos`, `cloud_provider`, `region`, `instance_type`, `instance_id`, `python_version`, `platform`
327
+
328
+ ---
329
+
330
+ ### `pa.config` — Configuration
331
+
332
+ ```python
333
+ from propalgos.config import get_config
334
+
335
+ cfg = get_config()
336
+ cfg.api_url # "https://api.propalgos.ai"
337
+ cfg.token # from PROPALGOS_TOKEN env
338
+ cfg.is_on_platform # True if PROPALGOS_INSTANCE_ID is set
339
+ cfg.cache_dir # ~/.cache/propalgos
340
+ ```
341
+
342
+ **Environment variables:**
343
+
344
+ | Variable | Default | Description |
345
+ |----------|---------|-------------|
346
+ | `PROPALGOS_API_URL` | `https://api.propalgos.ai` | Backend API URL |
347
+ | `PROPALGOS_TOKEN` | `None` | Auth token |
348
+ | `PROPALGOS_ENV` | `production` | Environment name |
349
+ | `PROPALGOS_CACHE_DIR` | `~/.cache/propalgos` | Disk cache directory |
350
+ | `PROPALGOS_INSTANCE_ID` | `None` | Set automatically on PropAlgos instances |
351
+ | `PROPALGOS_CUDF_AUTO` | `1` | Set to `0` to disable auto GPU acceleration on-platform |
352
+
353
+ ---
354
+
355
+ ### `pa.exceptions` — Error Hierarchy
356
+
357
+ All exceptions inherit from `PropAlgosError(message, code)`.
358
+
359
+ | Exception | Code | Description |
360
+ |-----------|------|-------------|
361
+ | `PropAlgosError` | varies | Base exception with machine-readable `code` |
362
+ | `AuthenticationError` | `auth_error` | Invalid or expired token |
363
+ | `APIError` | `api_error` | Backend API call failed (`status_code`, `response_body`) |
364
+ | `InsufficientCreditsError` | `insufficient_credits` | Balance too low (`balance`, `required`) |
365
+ | `DataError` | `data_error` | Market data fetch failed |
366
+ | `BacktestError` | `backtest_error` | Unrecoverable backtest issue |
367
+ | `ConfigError` | `config_error` | Missing or invalid configuration |
368
+
369
+ ---
370
+
371
+ ## GPU Acceleration
372
+
373
+ On PropAlgos GPU instances with RAPIDS installed, `import propalgos` automatically activates `cudf.pandas` — all pandas operations across the SDK and your own code run on the GPU with zero code changes:
374
+
375
+ ```python
376
+ import propalgos as pa
377
+ import pandas as pd
378
+
379
+ # both use GPU transparently — no %load_ext or manual setup needed
380
+ prices = pa.data.prices("SPY", start="2020-01-01")
381
+ df = pd.read_parquet("my_data.parquet") # also GPU-accelerated
382
+ ```
383
+
384
+ Auto-activation requires `PROPALGOS_INSTANCE_ID` (set automatically on PropAlgos instances) and a RAPIDS kernel. It's a no-op when either condition isn't met.
385
+
386
+ **Opt out** (for benchmarking or debugging):
387
+
388
+ ```bash
389
+ export PROPALGOS_CUDF_AUTO=0
390
+ ```
391
+
392
+ **Off-platform** (local dev, Colab, etc.) — activate manually before importing propalgos:
393
+
394
+ ```python
395
+ %load_ext cudf.pandas # or: import cudf.pandas; cudf.pandas.install()
396
+
397
+ import propalgos as pa
398
+ ```
399
+
400
+ ---
401
+
402
+ ## Development
403
+
404
+ ```bash
405
+ cd sdk/python
406
+
407
+ # install with dev + viz extras
408
+ pip install -e ".[dev,viz]"
409
+ # or with uv
410
+ uv sync --extra dev
411
+
412
+ # run tests (130 tests)
413
+ uv run -- python -m pytest tests/ -v
414
+
415
+ # lint
416
+ uv run -- ruff check src tests
417
+
418
+ # typecheck
419
+ uv run -- mypy src
420
+ ```
421
+
422
+ ### Test files
423
+
424
+ | File | Coverage |
425
+ |------|----------|
426
+ | `test_import.py` | Package structure, namespaces, exports |
427
+ | `test_signals.py` | All 8 signal functions + combine, raw RSI, `rsi_stacked`, `scan` |
428
+ | `test_factors.py` | Performance and risk metrics |
429
+ | `test_backtest.py` | Engine, results, costs, edge cases |
430
+ | `test_viz.py` | Heatmap, strip, theme modes, colorscales, monthly returns |
431
+ | `test_data.py` | Crypto providers, dataset registry, `load()`, `list_datasets()`, `list_symbols()` |
432
+
433
+ ---
434
+
435
+ ## License
436
+
437
+ Proprietary — PropAlgos, Inc. See [LICENSE](./LICENSE).