Interactive Brokers Client Services
Jun 17 12:40 AM
Message Center Notification
Interactive Brokers ticket response regarding Kanex account messaging.
Joaquín Medina
Jun 17 12:34 AM
RE: Re:[## 708 ##] RE: RMA for EXT-4KHD70M
AVIT Vision requests credit memo for destroyed equipment per RMA 708.
Microsoft Outlook
Jun 16 10:36 PM
Undeliverable: FW: TIER 3 Trending Stocks Part 2 (1 New Red Candle): $DELL, $OSCR, $ONDS, $ZETA, $LMND and $TMC (June 17, 2026-daily)
Microsoft Outlook: Undeliverable: FW: TIER 3 Trending Stocks Part 2 (1 New Red
Interactive Brokers Client Services
Jun 16 9:59 PM
Security Notice for User k******8: Verify Log In
Fake Interactive Brokers security alert requesting account verification.
Microsoft Outlook
Jun 16 9:38 PM
Undeliverable: FW: $QCOM (June 17, 2026-daily)
Microsoft Outlook: Undeliverable: FW: $QCOM (June 17, 2026-daily)
TDhruv Sharma
Jun 16 9:05 PM
[Teams oneOnOne] (Teams DM)
Dhruv Sharma: [Teams oneOnOne] (Teams DM)
Fabiola Hernandez
Jun 16 6:55 PM
Tomorrow is Spirit Day – Souvenir T-Shirt Day
Spirit Day reminder: kids invited to wear souvenir t-shirt tomorrow at camp.
Derrick
Jun 16 6:19 PM
Request for More Info: EXT-USBC2XI-100M - Dual-Host USB 3.2 Gen 1 Extender over CAT6a — USB-C & USB-B Inputs, 100m/328ft
Product inquiry for USB extender; requesting pricing, specs, availability.
Sydnee Agent (AI)
Jun 16 6:00 PM
[Spread Cal] 2026-06-17 — per-stock max_spread_bps results
Sydnee Agent (AI): [Spread Cal] 2026-06-17 — per-stock max_spread_bps results
Sydnee Agent (AI)
Jun 16 5:40 PM
[Calibration Daily] 2026-06-17
Sydnee Agent (AI): [Calibration Daily] 2026-06-17
Sydnee Agent (AI)
Jun 16 5:30 PM
Sydnee algo daily — dev $-2,699 · prod $+0 · 6d window
Sydnee Agent (AI): Sydnee algo daily — dev $-2,699 · prod $+0 · 6d window
Find My
Jun 16 5:24 PM
A sound was played on Kelvin’s iPad mini.
Find My: A sound was played on Kelvin’s iPad mini.
Sammy Cemo, Matt Pourcho and Anthony DeLorenzo
Jun 16 4:04 PM
New Pricing | Fortune 40 Credit | STNL Industrial | 11 Yr. WALT | SoCal
⚠ PHISHING: employee impersonation: display name matches 'anthony' but sender is cbre.com
Microsoft Store
Jun 16 3:23 PM
Meet the new Surface lineup—with limited-time offers
Microsoft Store: Meet the new Surface lineup—with limited-time offers
[email protected]
Jun 16 2:34 PM
New Funding Program
Funding broker offering working capital solutions and consolidation services.
Sammy Cemo and Anthony DeLorenzo
Jun 16 2:03 PM
Single-Story Owner-User Offering in Newport Beach
⚠ PHISHING: employee impersonation: display name matches 'anthony' but sender is cbre.com
Aarti Gupta
Jun 16 1:53 PM
Re: CR-TOUCH6R 6" Widescreen Touch Panel with Knob, RS232/RS485 & PoE
Aarti Gupta: Re: CR-TOUCH6R 6" Widescreen Touch Panel with Knob, RS232/RS
[email protected]
Jun 16 1:43 PM
Action required: Your June booking bonuses expire soon
⚠ PHISHING: phishing subject pattern: 'Action required' from external sender vacationoffer.com
TAnthony Patino
Jun 16 1:30 PM
[Teams oneOnOne] (Teams DM)
LK account overdrawn; bank fee applied, needs replenishment before QB charge.
TAnthony Patino
Jun 16 1:27 PM
[Teams oneOnOne] (Teams DM)
Anthony Patino sent a brief Teams DM referencing 'LK'.
TAnthony Patino
Jun 16 1:27 PM
[Teams oneOnOne] (Teams DM)
Anthony Patino reports insufficient funds issue.
Amazon Payments
Jun 16 12:44 PM
Action requise sur le compte Amazon Payments
Fake Amazon Payments suspension notice in French requesting account verification.
Nick Daniel
Jun 16 11:04 AM
Quick question
TriNet HR solution sales inquiry.
Aarti Gupta
Jun 16 10:04 AM
Re: Order help #1227
Aarti Gupta: Re: Order help #1227
Aarti Gupta
Jun 16 10:03 AM
Re: Order help #1227
Aarti Gupta: Re: Order help #1227
Aarti Gupta
Jun 16 9:59 AM
EXT-USBCPD4K-70M 18Gbps USB-C 4K60 HDBaseT 3.0 Extender with 100W PD (70m)
Aarti Gupta: EXT-USBCPD4K-70M 18Gbps USB-C 4K60 HDBaseT 3.0 Extender with
Sean McGinley
Jun 16 9:58 AM
Order help #1227
Customer inquiry about HDMI extender transmitter compatibility for order #1227.
IBKR FYI
Jun 16 9:51 AM
FYI: Upcoming Exchange Holidays
Exchange holiday notice: MIAX, NASDAQ, NYSE closed June 19.
IBKR FYI
Jun 16 9:27 AM
FYI: Upcoming Exchange Holidays
NASDAQ/MIAX exchange holiday June 19, 2026 — no trading.
Hims
Jun 16 9:02 AM
Kelvin - action required on your account
⚠ PHISHING: phishing subject pattern: 'action required' from external sender icloud.com
[email protected]
Jun 16 9:02 AM
You have a new estimate
Suspicious medical estimate link from Providence—verify legitimacy before clicking.
Mail Delivery System
Jun 16 8:20 AM
Mail delivery failed [Invoice #36077 PO: SH260526762J]
Mail delivery failed for invoice #36077 to Mike Vanderkamp; recipient address rejected.
Mail Delivery System
Jun 16 8:19 AM
Mail delivery failed [Invoice #36078 PO: SH260430677J]
Mail delivery failed: [email protected] → [email protected] for invoice #36078.
Mail Delivery System
Jun 16 8:19 AM
Mail delivery failed [Invoice #36079 PO: SH2606101007J]
Mail delivery failure: invoice to [email protected] rejected by recipient server.
TDhruv Sharma
Jun 16 8:16 AM
[Teams oneOnOne] (Teams DM)
Dhruv Sharma: [Teams oneOnOne] (Teams DM)
Zoho Campaigns
Jun 16 7:55 AM
Campaign "NEW USB-C + USB-B Dual-Host Extender · 100m" has been successfully Sent - Zoho Campaigns
Zoho Campaigns notification: USB-C/USB-B extender product campaign sent successfully.
Ali Pacheco
Jun 16 7:53 AM
Request for More Info: EXT-USBC2XI-100M - Dual-Host USB 3.2 Gen 1 Extender over CAT6a — USB-C & USB-B Inputs, 100m/328ft
Product inquiry for USB 3.2 extender from external vendor.
KanexPro
Jun 16 7:51 AM
NEW USB-C + USB-BDual-Host Extender · 100m
KanexPro: NEW USB-C + USB-BDual-Host Extender · 100m
KanexPro
Jun 16 7:50 AM
NEW USB-C + USB-BDual-Host Extender · 100m
KanexPro: NEW USB-C + USB-BDual-Host Extender · 100m
KanexPro
Jun 16 7:50 AM
NEW USB-C + USB-BDual-Host Extender · 100m
KanexPro: NEW USB-C + USB-BDual-Host Extender · 100m
KanexPro
Jun 16 7:49 AM
NEW USB-C + USB-BDual-Host Extender · 100m
KanexPro: NEW USB-C + USB-BDual-Host Extender · 100m
TDhruv Sharma
Jun 16 7:33 AM
[Teams oneOnOne] (Teams DM)
Dhruv Sharma: [Teams oneOnOne] (Teams DM)
TDhruv Sharma
Jun 16 7:32 AM
[Teams oneOnOne] (Teams DM)
Dhruv Sharma: [Teams oneOnOne] (Teams DM)
Bank of America
Jun 16 6:16 AM
Your available account balance is low
Bank of America: Your available account balance is low
Let's Talk Supply Chain
Jun 16 6:01 AM
Are you ready?
Suspicious meeting confirmation from unknown sender with obfuscation.
Interactive Brokers Client Services
Jun 16 5:18 AM
Message Center Notification
Interactive Brokers ticket response regarding Kanex account notification.
Benjamin & Williams
Jun 16 5:03 AM
Commercial Claim Discovery Documents Our file:D-8222 Debtor: VICTORIA ROPA ELEGANTE
Fake debt collector demanding payment on unknown commercial claim within 24h.
IBKR FYI
Jun 16 5:01 AM
FYI: Option Expiration Notification
Oracle options expiring 18JUN2026 — immediate action required.
IBKR FYI
Jun 16 5:00 AM
FYI: Option Expiration Notification
MSTR call option expiring 18JUN2026; action needed if extending position.
Sydnee Agent (AI)
Jun 16 4:25 AM
Sydnee nightly — exit_flow audit 2026-06-16 — 0P0 8P1 6R
Sydnee Agent (AI): Sydnee nightly — exit_flow audit 2026-06-16 — 0P0 8P1 6R
Sydnee nightly — performance audit 2026-06-13 — 0P0 0P1 5R
AI verdict
employee
high
· confidence: high
· by internal-exempt
“Sydnee Agent (AI): Sydnee nightly — performance audit 2026-06-13 — 0P0 0P1 5R”
Reasoning: @sydnee.ai is a protected domain — hard exemption
Sydnee nightly — performance audit — 2026-06-13
P0 findings: 0 P1 findings: 0 Risks: 5
- Area: Performance (Saturday theme)
- Branch: `dev` (534a5ab)
- Files scanned: `bot.py` (20 582 lines), `futures_client.py`, `polygon_client.py`,
`pages.py`, `docs/strategy_decisions.md`, `git log --oneline -10`
- Commits since last Sat audit (2026-06-06): 10 — all Day-page UI/perf (50d4e36 → 534a5ab)
- Bugs found (P0 / P1): 0 / 0
- Risks noted: 5 (2 new, 3 carry)
---
Full report (dev branch): https://github.com/kanex1/sydnee.signals/blob/dev/docs/audit_2026-06-13_performance.md
Reply FROM [email protected] to [email protected] to request fixes, e.g.:
"code_task on sydnee-signals-dev: apply fix for the P0 about RVOL threshold in bot.py"
Sydnee Agent will propose + you APPROVE (or plain 'approve') + auto-push to dev.
--- Full audit below (first 12 KB) ---
# Nightly Audit 2026-06-13 — PERFORMANCE
## Summary
- Area: Performance (Saturday theme)
- Branch: `dev` (534a5ab)
- Files scanned: `bot.py` (20 582 lines), `futures_client.py`, `polygon_client.py`,
`pages.py`, `docs/strategy_decisions.md`, `git log --oneline -10`
- Commits since last Sat audit (2026-06-06): 10 — all Day-page UI/perf (50d4e36 → 534a5ab)
- Bugs found (P0 / P1): 0 / 0
- Risks noted: 5 (2 new, 3 carry)
---
## Findings
### RISK (new): `/api/day/tick` — no response cache; Yahoo Finance rate-limit risk at 5s poll rate
**File:** `bot.py:11796`
**Evidence:**
```python
@app.route("/api/day/tick")
def api_day_tick():
...
snaps = pc.get_snapshots_batch(ALL_BATCH) # 1 Polygon HTTP call
...
fut = fc.get_futures_batch() # 4 parallel Yahoo Finance calls
return jsonify({...}) # no cache guard — always live
```
```python
# futures_client.py:69-83 — new ThreadPoolExecutor(max_workers=4) every call:
def get_futures_batch(symbols=DEFAULT_SYMBOLS) -> dict:
with ThreadPoolExecutor(max_workers=len(symbols)) as ex:
...
```
`/api/day/tick` is polled by two independent client loops:
- **Day page** (pages.py:9161): every 5s when the Day tab is open
- **Global nav Tone pill** (pages.py:159/187): every 30s on all pages
When the user is on the Day page: both loops fire from the same browser; the 5s rate
dominates → ~12 requests/min to the Flask endpoint. Each request:
1. Calls `pc.get_snapshots_batch(10 symbols)` → 1 Polygon HTTP call (OK — Polygon is paid tier)
2. Calls `fc.get_futures_batch()` → spawns `ThreadPoolExecutor(max_workers=4)` → 4 simultaneous
Yahoo Finance HTTP calls → 4 threads created + destroyed per tick
**Rate impact:** 12 endpoint calls/min × 4 Yahoo calls = **48 Yahoo Finance calls/min**.
`futures_client.py` line 9: "can rate-limit." Yahoo's unofficial rate limit is ~20–100
req/min per IP. Sustained 48/min is within the upper bound but fragile to temporary
spikes or Yahoo throttle changes.
**Thread overhead:** `ThreadPoolExecutor(max_workers=4)` is instantiated and destroyed 12×/min.
Python thread creation (stack allocation, OS context) adds ~1–5 ms of overhead per pool
creation × 12 = ~12–60 ms/min of pure setup cost. Low today (48 CPUs available); relevant
if the server is shared or the poll interval tightens.
**Impact when Yahoo rate-limits:** `get_futures_quote` returns `None`; `fut = {}` returned by
`get_futures_batch`; `api_day_tick` returns `"futures": {}`; the nav Tone score loses the
futures component (±1 delta swing on the 7-point scale); the Day page's futures strip
blanks out. The `api_day_analyze` prompt gets `[FUTURES] data unavailable` → degraded
Claude output. This is the same fail-open path that already triggered on 2026-06-01
("both MU webhooks refused by the flow gate... same code path that fail-opened on
Friday's SNDK 06:43 short for −$872" — strategy_decisions.md line 924 cites futures
correlation as a cause).
**Fix:** Add a 15s in-process response cache to `api_day_tick()`. The clock strip still
ticks in JS client-side; futures prices move on 1-min bars; 15s cache trades real-time
precision for ~12× fewer Yahoo calls (48/min → 4/min):
```python
# Class-level init:
self._day_tick_cache: dict | None = None
self._day_tick_cache_ts: float = 0.0
_DAY_TICK_CACHE_TTL = 15 # seconds
# Inside api_day_tick(), before snapshot fetch:
_now = time.time()
if (self._day_tick_cache is not None
and _now - self._day_tick_cache_ts < _DAY_TICK_CACHE_TTL):
return jsonify(self._day_tick_cache)
# ... fetch snaps, fut ...
_payload = {"indices": indices, "tone_etfs": tone_etfs, ...}
self._day_tick_cache, self._day_tick_cache_ts = _payload, time.time()
return jsonify(_payload)
```
Thread-safety note: Flask serves concurrent requests under Werkzeug threading; the
two-field update (cache dict + timestamp) is not atomic. A non-locked double-write is
safe here because the worst case is a redundant live fetch, not data corruption.
---
### RISK (new): `api_day_analyze` hardcodes `claude-sonnet-4-5-20250929` — one model generation behind current
**File:** `bot.py:12114`
**Evidence:**
```python
with client.messages.stream(
model="claude-sonnet-4-5-20250929", # ← Sonnet 4.5 (Sep 2025 checkpoint)
max_tokens=2500,
...
```
Current model per session config: `claude-sonnet-4-6`. The commit message for `cec0278`
says "Claude switched from Opus to Sonnet (~3x faster)" — that improvement was real and
landed. But the specific checkpoint `4-5-20250929` is one generation behind `claude-sonnet-4-6`,
which offers improved response quality and latency at the same tier.
**Impact:** Low. The model continues to work; `4-5-20250929` is not deprecated as of today.
The risk is model deprecation (Anthropic deprecation notice period is typically 6 months)
requiring a hotfix if not updated proactively, and marginally lower output quality vs
`claude-sonnet-4-6` for the daily market-tone call.
**Fix:** `bot.py:12114` — update to `"claude-sonnet-4-6"`. Single-line change.
---
### RISK (carry from 2026-06-06): `_scalp_signal_log_loop` — duplicate `hgetall` per symbol per tick
**File:** `bot.py:18525` (pending-event loop), `bot.py:18563` (new-event scan)
No change since 2026-06-06 filing. Confirmed still unfixed: no `_sym_hashes`
pre-cache present. At 8 syms × 40-event max-pending: up to 48 Redis `hgetall`
calls/tick for 8 unique keys → 6× redundancy. Low severity (localhost Redis);
becomes material if Redis moves off-host or symbol set expands.
Fix unchanged from prior audit: pre-cache `_sym_hashes = {sym: r.hgetall(...) for sym in syms}`
at the top of the tick body, reuse in both loops.
---
### RISK (carry from 2026-06-06): `api_scalp_signal_summary` + `api_scalp_signal_horizons` — no response cache; unbounded `count(*)` in summary
**File:** `bot.py:14466-14477` (summary), `bot.py:14479-14496` (horizons);
`core/database.py:426` (unbounded count(*))
No change since 2026-06-06 filing. Both endpoints fire 3–4 SQL queries per call with
no cache guard. `database.py:426` runs `SELECT count(*) FROM scalp_signal_log` with no
WHERE clause → full sequential scan growing O(table lifetime). With `SCALP_SIGNAL_LOG=true`
at ~120 events/hr, the table accumulates ~40K rows after 2 weeks. Not auto-polled by
dashboard today; impact limited to manual research-page loads.
Fix unchanged: 30s response cache (mirroring `_perf_cache` pattern) + windowed count.
---
### RISK (carry from 2026-05-23): `pd.concat + iloc[-500:]` double-alloc GC pressure in bar handlers
**File:** `bot.py:2942`, `bot.py:2963`, `bot.py:3092`
No change since 2026-05-23 filing. At 8 symbols × 5 TFs × ~12 bar events/min:
~480 DataFrame alloc+GC cycles/min. Low severity at current scale.
---
## OK (checked, working or recently fixed)
**`api_day_analyze` 60s Redis cache (cec0278):**
`day_tone_cache:{bucket}` key confirmed in bot.py:11911; TTL logic is mode-aware
(60s RTH/pre-market, 1h Mon-Thu AH, 24h dead periods). Cache miss triggers a fresh
Claude call; cache hits replay as NDJSON stream preserving the same wire format
the frontend reads. ✓
**`_replay()` pop correctness:**
`cached_result.pop("analysis", "")` at bot.py:11931 operates on a request-local dict
from `_json.loads(r_cache.get(cache_key))` — fresh per request, Redis entry unmodified.
The pop intentionally separates the analysis text (sent as a "chunk" event) from the
metadata payload. Consistent with the live path which uses separate `metadata` and
`full_text` objects. ✓
**`api_day_tick` Polygon rate-limit:** `get_snapshots_batch` fetches 10 symbols in a
single batch HTTP call (one URL, comma-joined tickers param) — not 10 individual calls.
At 12/min: 12 Polygon batch calls/min, well within the paid tier quota. ✓
**`api_day_analyze` NDJSON streaming with Flask/Werkzeug:**
`Response(_stream(), mimetype="application/x-ndjson")` correctly streams each
generator yield as a chunk with Werkzeug's threaded dev server. No buffer-until-done
behaviour observed (confirmed by the user: "metadata renders in ~1s, text streams
progressively" — commit 24aeb48). ✓
**`_tv_scale_add_shares` P&L accounting:**
`_close_trade_in_store` (bot.py:1311) computes `pnl = (exit_price - t.entry_price)
× t.direction × t.shares`. After a scale-in, `t.entry_price` is the slot-weighted
average and `t.shares` is the total filled across all slots
(`_tv_scale_add_shares` bot.py:4402-4407). Formula is correct. ✓
**`_compute_period_stats` max_drawdown:**
Sequential equity-curve walk (bot.py:8503-8507) starting from 0; closed trades are
in time order from `all_trades()`. Correct standard max-drawdown computation. ✓
**Three carry risks from 2026-06-06:** confirmed not newly introduced (no related commits
this week). Still present; see carry sections above. ✓ (checked, not regressed)