Sentinel Binds v0.3.2 — window snapping and window groups
Two things NinjaTrader does not do, in the spirit of Quantower's window binds.
- SNAP — drag or resize any NT window and it clicks into exact alignment with every other NT window and the monitor work area, on release. Windows abut with no seam. Hold SHIFT to place freely.
- BIND — name a set of windows, Link it, and dragging any member carries the whole group live, holding relative positions.
- LAYOUTS — capture an arrangement under a name, re-apply it in one click.
No market data. No orders. No SentinelCore seam beyond fault logging. No Council wiring. That isolation is deliberate: it makes this the safest component in the suite to read, fork and extend, and it is the recommended first issue for outside contributors.
Install
Easiest — download sentinel-binds-v0.3.2-import.zip and use Tools ▸ Import ▸ NinjaScript Add-On… in NinjaTrader. Then Control Center ▸ New ▸ Sentinel Binds.
Reading first — sentinel-binds-v0.3.2.zip is the same code foldered like the repo, with the docs and licence included. Copy runtime/ and binds/ into Documents\NinjaTrader 8\bin\Custom\ and press F5.
Both include the shared runtime (SentinelCore v1.45.0, SentinelSkin). If you already run another Sentinel bundle, importing this will overwrite those shared files with the same-or-newer version — that is intended.
⚠ Requires
SentinelCorev1.41.0 or newerBinds is the only bundle in the suite with a runtime floor — it records swallowed faults through
SentinelCore.Swallow, which arrived in v1.41.0. Every other bundle compiles against any version.Every bundle ships its own copy of the runtime, so copying an older bundle over this one downgrades
SentinelCore. NinjaTrader compiles all ofbin\Custominto one assembly, so Binds then fails withCS0117and takes your whole tree down — not just Sentinel.Install the oldest bundle first and the newest last, or re-copy the newest runtime after any install. Releases here always carry the current runtime; a zip from elsewhere may not.
How to use it
The spec now opens with a full How to use it section: every control, the tick → name → Save bind → Link sequence, and a table decoding the live trk · snap · grp · LINK · why diagnostic.
Read the why field first when something seems dead. A swallowed exception presents as "the feature does nothing", which fits a hundred design mistakes; the actual exception text fits one.
Honest limits
- Layouts arrange, they do not spawn. Apply moves windows that are already open. NT exposes no supported API to open "a chart on GC with this template". Unmatched windows are reported by name — a layout that half-applied silently would be worse than one that refused.
- A link does not survive an F5 or a restart. The file persists, the live link does not. Re-Link.
- A closed-and-reopened member needs a re-Link — the old window handle is dead even though the title matches.
- Duplicate titles are ambiguous. Two charts with identical captions may bind the wrong one.
- Maximized or minimized members sit out moves until restored (shown greyed).
- Delete has no confirmation and no undo. Known; it is issue #1 on the good-first-issues list.
- Not a Workspaces replacement. Workspaces persist across sessions; this is within-session alignment and instant re-arrangement.
If it throws a window off-screen
A bind can do this by design, so the antidote does not depend on the tool: Sentinel\tools\rescue-windows.ps1 is pure Win32, enumerates NinjaTrader's top-level windows, and works even when the Control Center is unreachable and no F5 is possible. In-app, Apply on a saved bind does the same job.
For contributors
NinjaTrader runs each window on its own dispatcher thread. Reading another window's .Left / .IsVisible / .WindowState throws every time, from any central loop — and WindowInteropHelper(w).Handle throws off-thread too. All geometry here is Win32 on the HWND. v0.1.x used WPF geometry, threw on every snap, had the exception swallowed, and presented as "nothing happens" through three wrong theories. The spec keeps that debugging record because the method is the lesson.