FINBOT CLIENT INTEGRATION — delivery 1.0.0

START ON YOUR MAC
1. Extract finbot-client-integration.zip into a new folder. Keep this separate
   from your running gateway, engine, credentials and databases.
2. Double-click Start_FinBot.command. Requires Python 3.10 or newer; no pip
   packages, broker SDKs or new credentials are required.
3. Your browser opens http://127.0.0.1:8870/. Click Connect.
   If Finder does not launch it, open Terminal in this folder and run:
   python3 finbot_client.py --open-browser
4. Disconnect stops snapshot polling. Ctrl+C in Terminal stops the client.

This package installs nothing over the existing gateway and does not restart it.
The local client uses port 8870, leaving your port 8765 gateway untouched. If
8870 is occupied, run python3 finbot_client.py --port 8871 --open-browser.
No scheduled/background service is installed. The Mac client process and browser
must remain open for polling. No assistant background monitoring is implied.

REQUEST BOUNDARY
Default source: https://qzotic-gateway.sotality.com/api/snapshot
The client sends GET requests; your existing system handles authorization and
broker access. No token is requested, loaded, generated, logged or stored here.
It does not bypass a 401/403: polling stops and displays the host decision.
A successful JSON response is interpreted as a host report, not proof of broker
identity, independently reconciled balances, or permission to trade.

Use an alternate previously supplied root only if your host maps it to snapshots:
python3 finbot_client.py --snapshot-url https://sotality.com --open-browser
Allowed exact hosts are qzotic-gateway.sotality.com and sotality.com; only HTTPS
root or /api/snapshot paths are accepted. Redirects, query credentials and URL
userinfo are rejected. No direct Alpaca fallback exists.

SUPPORTED SNAPSHOTS
A. Your supplied gateway format:
  {"status":"SNAPSHOT_PROCESSED_SUCCESS","data":{
    "portfolio":{"balance":"...","equity":"...","currency":"USD"},
    "research":{"signals":[{"symbol":"...","signal":"..."}]},"ledger":[]}}
B. The previously delivered dashboard export format: captured_at, account_mode,
   orders, and optional portfolio/research data. Extra security metadata is not
   reimplemented or changed; it is not interpreted as independent verification.

Optional captured_at must be timezone-aware. Without it, source freshness is
unknown; receipt time is shown separately. Missing financial fields stay absent
and render as a dash. Empty arrays mean zero records; absent arrays mean not
reported. Host-reported zeros cannot be distinguished from zeros fabricated by
an upstream component; this client cannot repair an ambiguous host response.

Financial values use exact decimal parsing, including decimal JSON numbers, and
are displayed without conversion to binary floating point. Source amounts have
bounded precision/range. Prices are charted separately by symbol using exact
integer normalization. No P&L or equity-return curve is invented.

Signals support text or objects with symbol, signal, action, status, reason,
strategy, price, confidence, score, timestamp. Ledger rows support id, timestamp,
symbol, side, qty, price, allocation_spent, status, alpaca_order_id. Unrecognized
fields are excluded; unsupported row structures generate a visible error.

CONNECTION BEHAVIOR
Click Connect for one request, then refresh approximately every five seconds.
Only one request runs at a time. Read failures back off to at most 60 seconds.
Authorization rejection stops polling. Disconnect cancels pending requests and
ignores late responses. Last received values are retained on errors with an
explicit connection message and source freshness label. The bridge retains no
snapshots on disk and does not expose raw upstream error bodies or private fields.
The bridge listens only on 127.0.0.1, checks Host/Origin and has no write routes.

TESTS
python3 -m unittest discover -s . -v
node test_monitor.cjs               (Node is needed only for development tests)

18 Python tests and 8 monitor scenarios passed. Three exact-decimal chart cases
also passed; compile, JavaScript syntax and launcher shell checks passed.
Tests cover request failures, authorization stops, precision, duplicate keys,
retention of last values, disconnect races, local HTTP integration and origin
isolation. Test data is synthetic and not seeded into the actual dashboard.
Browser rendering could not be tested here because the browser executable was
unavailable. Actual Mac installation and host data acceptance remain unverified.

An optional one-shot check prints status/counts only, not financial values:
python3 finbot_client.py --check
A delivery-time read-only check reported UPSTREAM_HTTP_ERROR. No order was sent.

SCOPE
Completed: client request bridge, supplied-format parsing, local dashboard,
portfolio/signals/activity views, exact per-symbol price charts, manual start/stop,
error handling, freshness reporting, tests and launcher.
This is the requested client integration package. It is not a replacement trading
engine, broker connector, gateway security system or certification of live trading.
Your running server, business plan and private implementation remain unchanged.
