-
Notifications
You must be signed in to change notification settings - Fork 0
Add numeric stack constraints and telemetry preflight #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Newcoderorigin
wants to merge
1
commit into
main
Choose a base branch
from
codex/add-ui.yml-configuration-for-ui-parameters-fpkfln
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,40 +1,68 @@ | ||
| # porjectx | ||
|
|
||
| ## Dependency compatibility | ||
| ## Reproducible environment bootstrap | ||
|
|
||
| The `toptek/requirements-lite.txt` file pins the scientific stack to keep it | ||
| compatible with the bundled scikit-learn release: | ||
| The numeric stack is pinned via [`constraints.txt`](constraints.txt) to avoid the | ||
| ABI/runtime mismatches that previously caused NumPy/SciPy import errors. The | ||
| root [`requirements.txt`](requirements.txt) includes that constraint file and | ||
| pulls in the toolkit's dependencies from `toptek/requirements-lite.txt`. | ||
|
|
||
| - `scikit-learn==1.3.2` | ||
| - `numpy>=1.21.6,<1.28` | ||
| - `scipy>=1.7.3,<1.12` | ||
| On Windows, run the helper script to recreate a clean environment and verify the | ||
| stack: | ||
|
|
||
| These ranges follow the support window published by scikit-learn 1.3.x and are | ||
| also consumed transitively by `toptek/requirements-streaming.txt` through its | ||
| `-r requirements-lite.txt` include. Installing within these bounds avoids the | ||
| ABI mismatches that occur with the NumPy/SciPy wheels when using newer major | ||
| releases. In particular, upgrading NumPy beyond `<1.28` causes SciPy to raise | ||
| its "compiled against NumPy 1.x" `ImportError`, mirroring the guidance already | ||
| documented in `toptek/README.md`. | ||
| ```powershell | ||
| .\scripts\setup_env.ps1 | ||
| ``` | ||
|
|
||
| ## Verifying the environment | ||
| The script rebuilds `.venv`, installs from `requirements.txt`, then prints | ||
| `STACK_OK` followed by the resolved versions in JSON form. The check ensures the | ||
| runtime matches `numpy==1.26.4`, `scipy==1.10.1`, and `scikit-learn==1.3.2` | ||
| exactly alongside compatible `pandas`, `joblib`, and `threadpoolctl` wheels. | ||
|
|
||
| Use Python **3.10 or 3.11**—matching the guidance in `toptek/README.md`'s | ||
| quickstart—to stay within the wheel support window for SciPy and | ||
| scikit-learn 1.3.x. Python 3.12 is currently unsupported because prebuilt | ||
| SciPy/scikit-learn wheels for that interpreter depend on NumPy ≥1.28 and | ||
| SciPy ≥1.12, which exceed this project's pinned ranges. Create and activate a | ||
| compatible virtual environment, then install and check for dependency issues: | ||
| For POSIX shells the equivalent manual steps are: | ||
|
|
||
| ```bash | ||
| python -m venv .venv | ||
| source .venv/bin/activate | ||
| pip install --upgrade pip | ||
| pip install -r toptek/requirements-lite.txt | ||
| pip check | ||
| pip install -r requirements.txt | ||
| ``` | ||
|
|
||
| The final `pip check` call should report "No broken requirements found", | ||
| confirming that the pinned dependency set resolves without conflicts. Users on | ||
| Python 3.12 should downgrade to Python 3.10/3.11 or wait for a dependency | ||
| refresh that supports NumPy ≥1.28 and SciPy ≥1.12 before proceeding. | ||
| ## Runtime telemetry and guardrails | ||
|
|
||
| The entry point now executes `toptek.core.utils.assert_numeric_stack()` and | ||
| `toptek.core.utils.set_seeds(42)` during startup. Version validation writes a | ||
| structured report to `reports/run_stack.json` so crash reports include the exact | ||
| Python and numeric-library versions. Structured logging is initialised via | ||
| `logging.basicConfig` with a rotating file handler targeting | ||
| `logs/toptek_YYYYMMDD.log` alongside console output, keeping telemetry for both | ||
| CLI and GUI sessions. | ||
|
|
||
| ## UI configuration surface | ||
|
|
||
| The manual trading shell and Tkinter dashboard read defaults from | ||
| [`configs/ui.yml`](configs/ui.yml). The file ships with sensible demo values so | ||
| the GUI renders without external data sources: | ||
|
|
||
| - `appearance` — theme token (currently `dark`) and accent family used by the | ||
| style registry. | ||
| - `shell` — defaults for the research symbol/timeframe, training lookback, | ||
| calibration flag, simulated backtest window, and preferred playbook. | ||
| - `chart` — LiveChart refresh cadence (`fps`), point budget, and price | ||
| precision used by streaming widgets. | ||
| - `status` — copy for the status banners shown in the Login, Train, Backtest, | ||
| and Guard tabs so product teams can retune messaging without touching code. | ||
|
|
||
| Operators can override the YAML at runtime with environment variables or CLI | ||
| flags: | ||
|
|
||
| - Environment variables follow the `TOPTEK_UI_*` convention, e.g. | ||
| `TOPTEK_UI_SYMBOL`, `TOPTEK_UI_INTERVAL`, `TOPTEK_UI_LOOKBACK_BARS`, | ||
| `TOPTEK_UI_CALIBRATE`, `TOPTEK_UI_FPS`, and `TOPTEK_UI_THEME`. | ||
| - CLI switches (`--symbol`, `--timeframe`, `--lookback`, `--model`, `--fps`) | ||
| apply the same overrides for one-off runs and are reflected back into the GUI | ||
| when it launches. | ||
|
|
||
| These controls keep the default Topstep demo intact while making it easy to | ||
| point the toolkit at alternative markets or stress-test higher frequency charts | ||
| without editing source files. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| appearance: | ||
| theme: dark | ||
| accent: violet | ||
| shell: | ||
| symbol: ES=F | ||
| interval: 5m | ||
| research_bars: 240 | ||
| lookback_bars: 480 | ||
| calibrate: true | ||
| model: logistic | ||
| simulation_bars: 720 | ||
| playbook: momentum | ||
| chart: | ||
| fps: 12 | ||
| max_points: 180 | ||
| price_decimals: 2 | ||
| status: | ||
| login: | ||
| idle: "Awaiting verification" | ||
| saved: "Saved. Run verification to confirm access." | ||
| verified: "All keys present. Proceed to Research ▶" | ||
| training: | ||
| idle: "Awaiting training run" | ||
| success: "Model artefact refreshed. Continue to Backtest ▶" | ||
| backtest: | ||
| idle: "No simulations yet" | ||
| success: "Sim complete. If expectancy holds, draft a manual trade plan ▶" | ||
| guard: | ||
| pending: "Topstep Guard: pending review" | ||
| intro: "Manual execution only. Awaiting guard refresh..." | ||
| defensive_warning: "DEFENSIVE_MODE active. Stand down and review your journal before trading." |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| numpy==1.26.4 | ||
| scipy==1.10.1 | ||
| scikit-learn==1.3.2 | ||
| joblib>=1.3,<2 | ||
| threadpoolctl>=3,<4 | ||
| pandas>=1.5,<2.3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| [build-system] | ||
| requires = ["setuptools>=61", "wheel"] | ||
| build-backend = "setuptools.build_meta" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| -c constraints.txt | ||
| -r toptek/requirements-lite.txt |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| param( | ||
| [string]$Python = "py -3.11" | ||
| ) | ||
|
|
||
| $ErrorActionPreference = "Stop" | ||
|
|
||
| if (Test-Path ".venv") { | ||
| Remove-Item ".venv" -Recurse -Force | ||
| } | ||
|
|
||
| & $Python -m venv .venv | ||
|
|
||
| $venvPath = Join-Path (Resolve-Path ".venv").Path "Scripts" | ||
| $venvPython = Join-Path $venvPath "python.exe" | ||
|
|
||
| & $venvPython -m pip install --upgrade pip | ||
| & $venvPython -m pip install -r requirements.txt | ||
|
|
||
| $stackCheck = @" | ||
| import importlib | ||
| import json | ||
| import platform | ||
|
|
||
| modules = ["numpy", "scipy", "sklearn", "pandas", "joblib", "threadpoolctl"] | ||
| versions = {name: importlib.import_module(name).__version__ for name in modules} | ||
| print("STACK_OK") | ||
| print(json.dumps({ | ||
| "python": platform.python_version(), | ||
| "versions": versions, | ||
| }, indent=2)) | ||
| "@ | ||
|
|
||
| & $venvPython -c $stackCheck |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| from __future__ import annotations | ||
| from pathlib import Path | ||
|
|
||
| import pytest | ||
|
|
||
| from core import ui_config | ||
|
|
||
|
|
||
| def test_load_ui_config_defaults(tmp_path: Path) -> None: | ||
| path = tmp_path / "ui.yml" | ||
| path.write_text("{}\n", encoding="utf-8") | ||
| cfg = ui_config.load_ui_config(path, env={}) | ||
| assert cfg.shell.symbol == "ES=F" | ||
| assert cfg.shell.interval == "5m" | ||
| assert cfg.shell.research_bars == 240 | ||
| assert cfg.chart.fps == 12 | ||
| assert cfg.status.login.idle == "Awaiting verification" | ||
| assert cfg.appearance.theme == "dark" | ||
|
|
||
|
|
||
| def test_load_ui_config_env_overrides(tmp_path: Path) -> None: | ||
| path = tmp_path / "ui.yml" | ||
| path.write_text( | ||
| "shell:\n symbol: ES=F\n calibrate: true\nchart:\n fps: 8\n", | ||
| encoding="utf-8", | ||
| ) | ||
| env = { | ||
| "TOPTEK_UI_SYMBOL": "NQ=F", | ||
| "TOPTEK_UI_CALIBRATE": "false", | ||
| "TOPTEK_UI_LOOKBACK_BARS": "960", | ||
| "TOPTEK_UI_FPS": "24", | ||
| "TOPTEK_UI_THEME": "dark", | ||
| } | ||
| cfg = ui_config.load_ui_config(path, env=env) | ||
| assert cfg.shell.symbol == "NQ=F" | ||
| assert cfg.shell.calibrate is False | ||
| assert cfg.shell.lookback_bars == 960 | ||
| assert cfg.chart.fps == 24 | ||
| assert cfg.appearance.theme == "dark" | ||
|
|
||
|
|
||
| def test_load_ui_config_validation(tmp_path: Path) -> None: | ||
| path = tmp_path / "ui.yml" | ||
| path.write_text("chart:\n fps: 0\n", encoding="utf-8") | ||
| with pytest.raises(ValueError): | ||
| ui_config.load_ui_config(path, env={}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| """Tests for numeric stack validation and logging utilities.""" | ||
|
|
||
| import json | ||
| import logging | ||
| from logging.handlers import RotatingFileHandler | ||
| from pathlib import Path | ||
|
|
||
| import numpy as np | ||
| import pytest | ||
|
|
||
| from toptek.core import utils | ||
|
|
||
|
|
||
| def test_assert_numeric_stack_writes_report(tmp_path: Path) -> None: | ||
| reports_dir = tmp_path / "reports" | ||
| versions = utils.assert_numeric_stack(reports_dir=reports_dir) | ||
|
|
||
| report_path = reports_dir / "run_stack.json" | ||
| assert report_path.exists() | ||
|
|
||
| payload = json.loads(report_path.read_text(encoding="utf-8")) | ||
| assert payload["status"] == "ok" | ||
| assert payload["required"]["numpy"] == versions["numpy"] | ||
| assert payload["expected"]["scipy"] == utils.STACK_REQUIREMENTS["scipy"] | ||
|
|
||
|
|
||
| def test_assert_numeric_stack_raises_on_mismatch( | ||
| monkeypatch: pytest.MonkeyPatch, tmp_path: Path | ||
| ) -> None: | ||
| monkeypatch.setitem(utils.STACK_REQUIREMENTS, "numpy", "0.0.0") | ||
|
|
||
| with pytest.raises(RuntimeError) as excinfo: | ||
| utils.assert_numeric_stack(reports_dir=tmp_path) | ||
|
|
||
| assert "scripts/setup_env.ps1" in str(excinfo.value) | ||
|
|
||
| report = json.loads((tmp_path / "run_stack.json").read_text(encoding="utf-8")) | ||
| assert report["status"] == "error" | ||
|
|
||
|
|
||
| def test_set_seeds_reproducible() -> None: | ||
| utils.set_seeds(123) | ||
| first = np.random.random(3) | ||
| utils.set_seeds(123) | ||
| second = np.random.random(3) | ||
|
|
||
| assert np.allclose(first, second) | ||
|
|
||
|
|
||
| def test_configure_logging_installs_rotating_handler(tmp_path: Path) -> None: | ||
| root_logger = logging.getLogger() | ||
| original_handlers = list(root_logger.handlers) | ||
| for handler in original_handlers: | ||
| root_logger.removeHandler(handler) | ||
|
|
||
| try: | ||
| log_path = utils.configure_logging(tmp_path, level="INFO") | ||
| assert log_path.exists() | ||
| assert any( | ||
| isinstance(handler, RotatingFileHandler) | ||
| for handler in logging.getLogger().handlers | ||
| ) | ||
| finally: | ||
| for handler in logging.getLogger().handlers: | ||
| handler.close() | ||
| logging.getLogger().handlers.clear() | ||
| for handler in original_handlers: | ||
| logging.getLogger().addHandler(handler) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CLI now casts
args.lookbacktointand forwards it todata.sample_dataframe(lookback), but the integration test still stubssample_dataframewith a zero‑argument lambda and builds the namespace withlookback="90d". Whenrun_cliexecutes, the stub will raiseTypeError(unexpected positional argument) orValueErrorwhenint("90d")is evaluated, so the test suite cannot run. The stub needs to accept the new positional argument and the test should pass an integer lookback to match the updated CLI contract.Useful? React with 👍 / 👎.