Sydnee Inc Legal
Aug 15 7:55 PM
TEST — Veer 304E, how the Izeal reply will look
⚠ PHISHING: domain impersonation: display name contains 'sydnee' but sender is email.sydneeinc.com
Sydnee Inc Legal
Aug 15 7:46 PM
Veer Towers 304E - furnished 1BR, corporate housing
⚠ PHISHING: domain impersonation: display name contains 'sydnee' but sender is email.sydneeinc.com
Kelvin Yan
Aug 15 7:34 PM
Veer 304E — three drafts for review before sending
⚠ PHISHING: employee impersonation: display name matches 'kelvin yan' but sender is email.sydneeinc.com
Bank of America
Aug 15 5:44 PM
Your statement is available
Bank of America: Your statement is available
Bank of America
Aug 15 5:43 PM
Your statement is available
Bank of America: Your statement is available
Sydnee Agent (AI)
Aug 15 5:39 PM
[Calibration Daily] 2026-08-16
Sydnee Agent (AI): [Calibration Daily] 2026-08-16
Sydnee Inc Legal
Aug 15 5:34 PM
Access test 1 of 3 - link
⚠ PHISHING: domain impersonation: display name contains 'sydnee' but sender is email.sydneeinc.com
Sydnee Inc Legal
Aug 15 5:33 PM
Access test 3 of 3 - verified
⚠ PHISHING: domain impersonation: display name contains 'sydnee' but sender is email.sydneeinc.com
Sydnee Inc Legal
Aug 15 5:09 PM
Access test 3 of 3 - verified
⚠ PHISHING: domain impersonation: display name contains 'sydnee' but sender is email.sydneeinc.com
Sydnee Inc Legal
Aug 15 5:09 PM
Access test 1 of 3 - link
⚠ PHISHING: domain impersonation: display name contains 'sydnee' but sender is email.sydneeinc.com
Sydnee Inc Legal
Aug 15 4:48 PM
Access test 1 of 3 - link (opens straight away, no code)
⚠ PHISHING: domain impersonation: display name contains 'sydnee' but sender is email.sydneeinc.com
Microsoft Outlook
Aug 15 4:47 PM
Undeliverable: FW: Dr Cat's Video Insights on $NOW and $TEAM-Video 2 of 12 (August 16, 2026)
Microsoft Outlook: Undeliverable: FW: Dr Cat's Video Insights on $NOW and $TEAM
Microsoft Outlook
Aug 15 4:46 PM
Undeliverable: FW: Dr Cat's Video Insights on $ABCL-Video 3 of 12 (August 16, 2026)
Microsoft Outlook: Undeliverable: FW: Dr Cat's Video Insights on $ABCL-Video 3
Sydnee Inc Legal
Aug 15 4:26 PM
Veer 304E - all three access levels
⚠ PHISHING: domain impersonation: display name contains 'sydnee' but sender is email.sydneeinc.com
Sydnee Inc Legal
Aug 15 4:16 PM
Veer 304E - replacement links
⚠ PHISHING: domain impersonation: display name contains 'sydnee' but sender is email.sydneeinc.com
Sydnee Inc Legal
Aug 15 4:10 PM
Veer 304E - short links, one with a code
⚠ PHISHING: domain impersonation: display name contains 'sydnee' but sender is email.sydneeinc.com
Sydnee Inc Legal
Aug 15 4:04 PM
Your access code
⚠ PHISHING: domain impersonation: display name contains 'sydnee' but sender is email.sydneeinc.com
Sydnee Inc Legal
Aug 15 4:04 PM
Your access code
⚠ PHISHING: domain impersonation: display name contains 'sydnee' but sender is email.sydneeinc.com
Sydnee Inc Legal
Aug 15 4:00 PM
Veer 304E - test of the secure file links
⚠ PHISHING: domain impersonation: display name contains 'sydnee' but sender is email.sydneeinc.com
Sydnee Inc Legal
Aug 15 4:00 PM
Your access code
⚠ PHISHING: domain impersonation: display name contains 'sydnee' but sender is email.sydneeinc.com
Amazon Payments
Aug 15 12:52 PM
Action requise sur le compte Amazon Payments
Fake Amazon Payments suspension threat; credential harvesting attempt.
Guest Relations at The Ritz-Carlton, Laguna Niguel
Aug 15 10:49 AM
Kelvin, please complete the travel request form to customize your stay at The Ritz-Carlton, Laguna Niguel
Suspicious Ritz-Carlton email with obfuscation; potential credential theft attempt.
Manus Team
Aug 15 7:33 AM
ACTION REQUIRED: 7 days left to back up Kelvin Yan for future restoration
⚠ PHISHING: phishing subject pattern: 'ACTION REQUIRED' from external sender privaterelay.appleid.com
Benjamin & Williams
Aug 15 5:02 AM
Commercial Claim Discovery Documents Our file:D-8222 Debtor: VICTORIA ROPA ELEGANTE
Fake debt collection demand with 24h payment pressure; spoofed domain.
Sydnee Agent (AI)
Aug 15 4:15 AM
Sydnee nightly — PERFORMANCE audit 2026-08-15 — 0P0 2P1 13R
Sydnee Agent (AI): Sydnee nightly — PERFORMANCE audit 2026-08-15 — 0P0 2P1 13R
The Ritz-Carlton Reservations
Aug 15 4:12 AM
Plan for your upcoming stay at The Ritz-Carlton, Laguna Niguel on Monday, August 17, 2026
Ritz-Carlton reservation confirmation for August 17 stay at Laguna Niguel.
Tesla
Aug 15 12:55 AM
Full Self-Driving (Supervised) Subscription Renewed
Tesla FSD subscription auto-renewed for Model Y, $107.29/month.
Sydnee.ai Legal
Aug 14 9:22 PM
Jiao 移民案件最新进展说明(好消息,请放心)
⚠ PHISHING: domain impersonation: display name contains 'sydnee' but sender is email.sydnee.ai
KuCoin
Aug 14 6:38 PM
Dormancy Fee Deduction Notice
KuCoin dormancy fee deducted from account this month.
Tommy Wang (Wang IP Law)
Aug 14 6:30 PM
Re: I-485 Application (IOE0934359789 and IOE0934359788)
Tommy Wang (Wang IP Law): Re: I-485 Application (IOE0934359789 and IOE0934359788)
Bank of America
Aug 14 6:16 PM
We've sent your payment to SOUTHERN CALIFORNIA EDISON SCE as requested
Bank of America: We've sent your payment to SOUTHERN CALIFORNIA EDISON SCE as
Sydnee Agent (AI)
Aug 14 5:42 PM
[Calibration Daily] 2026-08-15
Sydnee Agent (AI): [Calibration Daily] 2026-08-15
Sydnee Agent (AI)
Aug 14 5:30 PM
Sydnee algo daily — dev $-2,239 · prod $+0 · 6d window
Sydnee Agent (AI): Sydnee algo daily — dev $-2,239 · prod $+0 · 6d window
Laguna Road Area Community Message
Aug 14 2:39 PM
1 New School Flyer for Your Child
School flyer: Congressional App Challenge signup opportunity.
Anthony Patino in Teams
Aug 14 2:34 PM
Anthony Patino sent a message
⚠ PHISHING: employee impersonation: display name matches 'anthony' but sender is teams.mail.microsoft
TAnthony Patino
Aug 14 1:34 PM
[Teams oneOnOne] (Teams DM)
Anthony Patino flagging ~$20k air shipment payment for approval.
Amy Burghardt
Aug 14 1:19 PM
RE: Meeting
Amy Burghardt: RE: Meeting
Mary Chmelka
Aug 14 1:07 PM
Survey invite to Ameritas California Language Assistance Program Survey
Ameritas requesting language preference survey for insurance benefits.
TAnthony Patino
Aug 14 12:47 PM
[Teams oneOnOne] (Teams DM)
Anthony Patino requesting updated HDCVT statement.
TAnthony Patino
Aug 14 12:45 PM
[Teams oneOnOne] (Teams DM)
Teams DM acknowledgment from Anthony Patino.
TAnthony Patino
Aug 14 12:45 PM
[Teams oneOnOne] (Teams DM)
Anthony Patino confirms E-like assessment via Teams DM.
TAnthony Patino
Aug 14 12:08 PM
[Teams oneOnOne] (Teams DM)
Anthony found something; not due for ~30 days.
TAnthony Patino
Aug 14 12:05 PM
[Teams oneOnOne] (Teams DM)
SAVLink payment $15,915 awaiting approval
TAnthony Patino
Aug 14 11:59 AM
[Teams oneOnOne] (Teams DM)
Anthony Patino internal Teams message about communications or notes.
TAnthony Patino
Aug 14 11:56 AM
[Teams oneOnOne] (Teams DM)
Anthony Patino confirming he will set something up now.
TAnthony Patino
Aug 14 11:56 AM
[Teams oneOnOne] (Teams DM)
Anthony Patino Teams DM about something that just came due recently.
TAnthony Patino
Aug 14 11:55 AM
[Teams oneOnOne] (Teams DM)
Anthony Patino confirms document dated 6/04 with net60 terms.
TAnthony Patino
Aug 14 11:54 AM
[Teams oneOnOne] (Teams DM)
SmartAV Link requesting payment of $15,915.
TAnthony Patino
Aug 14 11:47 AM
[Teams oneOnOne] (Teams DM)
Anthony reports received Iolo Capital invoice, needs approval to add to CC.
TAnthony Patino
Aug 14 11:25 AM
[Teams oneOnOne] (Teams DM)
Anthony Patino initiating a Teams call.
Sydnee nightly — DATA_QUALITY audit 2026-08-05 — 1P0 2P1 9R
AI verdict
employee
high
· confidence: high
· by internal-exempt
“Sydnee Agent (AI): Sydnee nightly — DATA_QUALITY audit 2026-08-05 — 1P0 2P1 9R”
Reasoning: @sydnee.ai is a protected domain — hard exemption
Sydnee nightly — DATA_QUALITY audit — 2026-08-05
P0 findings: 1 P1 findings: 2 Risks: 9
- Area: Data Quality (Wednesday rotation)
- Branch: `dev` (3051452 — docs(peak-monitor): hourly log 2026-08-04 13:10 PT)
- Files scanned: `bot.py` (24,173 lines), `polygon_client.py`, `core/screener.py`,
`core/database.py`, `core/indicators.py`, `docs/strategy_decisions.md`,
`docs/audit_2026-07-23_DATA_QUALITY.md`, `git log --oneline -30`
- **Bugs found (P0 / P1): 1 / 2 (all carried — no new bugs)**
- **Risks noted: 9 (6 carried + 3 new)**
**Cross-check:** `git log --oneline -30` shows zero commits to `bot.py`, `polygon_client.py`,
`core/`, or any strategy file since 2026-07-17. All subsequent commits are audit docs +
peak-monitor hourly logs. Carried bugs and risks verified at the same line numbers as
2026-07-23 DATA QUALITY audit. Three new risks surfaced from tonight's source sweep.
API endpoints (`dev.sydnee.ai`) not reachable from sandbox — source-only analysis applied
per audit instructions.
---
Full report (dev branch): https://github.com/kanex1/sydnee.signals/blob/dev/docs/audit_2026-08-05_DATA_QUALITY.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-08-05 — DATA QUALITY
## Summary
- Area: Data Quality (Wednesday rotation)
- Branch: `dev` (3051452 — docs(peak-monitor): hourly log 2026-08-04 13:10 PT)
- Files scanned: `bot.py` (24,173 lines), `polygon_client.py`, `core/screener.py`,
`core/database.py`, `core/indicators.py`, `docs/strategy_decisions.md`,
`docs/audit_2026-07-23_DATA_QUALITY.md`, `git log --oneline -30`
- **Bugs found (P0 / P1): 1 / 2 (all carried — no new bugs)**
- **Risks noted: 9 (6 carried + 3 new)**
**Cross-check:** `git log --oneline -30` shows zero commits to `bot.py`, `polygon_client.py`,
`core/`, or any strategy file since 2026-07-17. All subsequent commits are audit docs +
peak-monitor hourly logs. Carried bugs and risks verified at the same line numbers as
2026-07-23 DATA QUALITY audit. Three new risks surfaced from tonight's source sweep.
API endpoints (`dev.sydnee.ai`) not reachable from sandbox — source-only analysis applied
per audit instructions.
---
## Findings
### BUG [P0] (carried ×6 — first filed 2026-07-08, present in every audit since): `_tf15_trend` NameError in `elif _pending:` path — exit evaluation aborts for pending-reversal symbols
**File:** `bot.py:5483`
**Evidence:**
```python
# bot.py:5441 — immediate-fire path correctly assigns _tfmid_trend:
_tfmid_trend = ss.trends.get(15, 0)
# bot.py:5483 — elif _pending: path reads the never-assigned _tf15_trend:
_15m_with_pos = (_tf15_trend != 0 and _tf15_trend == t.direction) # ← NameError
# grep -c "_tf15_trend" bot.py → 1 (line 5483 only; no assignment in file)
```
**Impact:** `NameError` propagates and is caught by the outer `except Exception`
at `bot.py:2914–2917`, aborting all subsequent exit logic (TRIM1 at 5652, TRIM2 at
5585, OBV BE-stop at 5114, HOLD_CAP at 5154) for the life of `_pending_reversal=True`.
Root-cause of IREN/INTC TRIM1 silent-fail incidents.
**Fix:**
```python
# bot.py:5483 — one rename:
_15m_with_pos = (_tfmid_trend != 0 and _tfmid_trend == t.direction)
```
---
### BUG [P1] (carried ×7 — first filed DATA_QUALITY 2026-07-01): `_prev_rth_close` returns today's Polygon daily bar as "previous RTH close" — `extension_fade` never fires since go-live
**File:** `bot.py:1634–1641`
**Evidence:**
```python
# polygon_client.py:176 — Polygon daily bars stored PT-naive:
df["date"] = pd.to_datetime(df["t"], unit="ms", utc=True).dt.tz_convert(PT_TZ).dt.tz_localize(None)
# A 2026-08-05 ET session bar has t = 2026-08-05 00:00 UTC
# → 2026-08-04 17:00 PDT (tz-naive) → stored index = 2026-08-04 17:00
# bot.py:1638 — _prev_rth_close reads date from the tz-naive timestamp:
bar_d = pd.Timestamp(ts).date() # → 2026-08-04 (one day before the ET session!)
# today_et = datetime.now(ET).date() → 2026-08-05
# Condition bar_d < today_et is True → today's bar returned as "prev close"
```
`prev_close ≈ current_price`, so `move_from_prev ≈ 0`, `extended` flag never sets,
and `extension_fade` entries are silently unreachable.
**Impact:** `extension_fade` dead since 2026-04-19 (Polygon go-live for daily TF).
Gap-and-fade overnight setups — the strategy's strongest mean-reversion edge —
have not been identified or traded.
**Fix (previous audit's `hour >= 20` threshold is wrong — Polygon daily bars land at
`hour=17 PDT` or `hour=16 PST`):**
```python
# bot.py:1638 — replace:
bar_d = pd.Timestamp(ts).date()
# with:
_ts = pd.Timestamp(ts)
if _ts.hour >= 16: # PDT daily bar at 17:00; PST at 16:00
_ts = _ts + timedelta(hours=8) # recovers ET calendar date safely
bar_d = _ts.date()
```
---
### BUG [P1] (carried ×4 — first filed DATA_QUALITY 2026-07-16): `_ab_l2_flip_check` consecutive-count buffer not cleared on stale L2 snapshot — flip exit fires on non-consecutive opposing snapshots
**File:** `bot.py:20067–20069`
**Evidence:**
```python
def _ab_l2_flip_check(self, symbol, direction, threshold=3):
l2 = self._ab_latest_l2(symbol)
if not l2:
return False # ← returns False but DOES NOT clear self._ab_l2_hist[symbol]
...
buf = self._ab_l2_hist.setdefault(symbol, [])
if opposing:
buf.append(imb) # appends on next non-stale tick, compounding prior stale count
else:
self._ab_l2_hist[symbol] = []
```
`_ab_latest_l2` TTL=15 000 ms; loop sleeps 15s. Sub-millisecond DB write latency
routinely produces `age ≥ 15 001 ms` on alternate ticks. The persistent buffer lets
2 opposing snapshots + 1 stale tick satisfy the `threshold=3` consecutive check.
**Impact:** AB executor (paper MES/MNQ) may exit positions on false L2 flip signals.
**Fix:**
```python
# bot.py:20068–20069 — clear buf on stale:
if not l2:
if hasattr(self, "_ab_l2_hist"):
self._ab_l2_hist[symbol] = []
return False
```
---
### RISK (NEW — first filed tonight): `ss.last_rsi` assignment at `bot.py:5022` has no NaN guard — halted/constant-price stock permanently blinds RSI signal and exit for one bar cycle
**File:** `bot.py:5022`
**Evidence:**
```python
# bot.py:5022 — unguarded assignment:
ss.last_rsi = float(_rsi(close, 9).iloc[-1]) # no isnan() check
# _rsi() with constant price input:
# d = s.diff() → all zeros; ag=0, al=0; 0/0 → NaN; output is all-NaN series
# float(all_NaN.iloc[-1]) → nan
# → ss.last_rsi = nan
# Downstream consumers (no crash, but behavior changes):
# bot.py:5944: if ss.last_rsi <= _rsi_os: → nan <= 30 → False → no RSI extreme entry
# bot.py:5400: f"RSI(9)={ss.last_rsi:.0f}" → formats as "nan" in log string
# bot.py:5407/5410: RSI trim exits also gated on last_rsi comparison → silent skip
```
Previous audit (2026-07-23) stated "all callers fall back to 50.0 on NaN" but listed
only read sites (lines 5868, 5870, 7046, 17003), not line 5022 which is the write
site. The NaN persists until the next bar close where prices diverge.
**Impact:** A halted or data-frozen stock (flat close for 80+ bars) would have
`ss.last_rsi = nan`, silently blocking: (a) RSI extreme entry signal for the duration
of the freeze, and (b) RSI-based trim exits for any open position. Stop-loss and
ATR-trail exits still function.
**Fix:**
```python
# bot.py:5022 — match the pattern used at line 5868:
_rsi_val = float(_rsi(close, 9).iloc[-1])
ss.last_rsi = _rsi_val if not np.isnan(_rsi_val) else ss.last_rsi # retain prior value on NaN
```
---
### RISK (NEW — first filed tonight): `_fetch_bars` double-failure (Polygon empty + IBKR no bars) produces silent empty return — symbol stays `warming_up` indefinitely with no log
**File:** `bot.py:1648–1690`
**Evidence:**
```python
# bot.py:1673–1678 — Polygon path:
df = pc.fetch_bars(symbol, tf, dur, retries=retries)
if df is not None and len(df) > 0:
return df
logger.debug(...) # ← DEBUG only — invisible in prod
# bot.py:1680–1689 — IBKR path (no try/except):
bars = self.ib.reqHistoricalData(...)
if bars:
...
return df[...]
return pd.DataFrame() # ← silent empty on double failure; no additional log
```
Callers in `_load_history` (line 2869: `if len(df) > 0: ss.bars[tf] = df`) leave
`ss.bars[tf]` empty. Symbol stays in `warming_up` until real-time bars accumulate
(~6–7 hours for 5m MIN_BARS=80 at RTH pace). No log indicates which TF failed or
why.
**Impact:** During Polygon rate-limit events or after IBKR reconnect delays, one or
more symbols can silently start the session in `warming_up` with zero historical bars,
missing the opening RTH window entirely. The IBKR path also has no `try/except`,
so an IBKR exception (error 162, disconnection) during `_load_history` propagates to
the outer handler at line 1826 and sets `ss.status = "no_data"` instead.
**Fix:** Raise the Polygon empty log to WARNING, add try/except around the IBKR
`reqHistoricalData` call, and log explicitly on combined empty return:
```python
# after IBKR path returns empty:
logger.warning("_fetch_bars: both Polygon and IBKR returned empty for %s %dm", symbol, tf)
return pd.DataFrame()
```
---
### RISK (NEW — first filed tonight): No freshness check on `ss.bars[tf]` content before strategy evaluation — stale bars from a dead feed drive live signals
**File:** `bot.py:4680` (`_evaluate_symbol` entry), `bot.py:4937–4955` (trend loop)
**Evidence:**
```python
# bot.py:4680 — only bar COUNT is checked, not bar AGE:
if len(signal_df) < MIN_BARS:
...
# bot.py:4941–4955 — trend computed from ss.bars[tf] regardless of when last bar arrived:
_, ms_tf, ml_tf = bx_sigs(ss.bars[tf]["close"])
ss.trends[tf] = new_trend # ← could be hours stale
```
There is no code of the form `time.time() - ss.bars[tf].index[-1]` anywhere in the
codebase. If the Polygon bar feed thread dies (exception in `_polygon_bar_feed_loop`)
or the IBKR live bar subscription silently drops, `ss.bars[tf]` stops accreting new
bars. `_evaluate_symbol` continues to fire on bar-close heartbeat using the frozen
DataFrame — same RSI, same BXt signal — potentially opening new positions on hours-old
data.
The only existing freshness guards are on the **tick-level WS quote** (line 4267:
`_ws_age < 5000` — 5-second threshold on the WebSocket price) and the Redis tape
baseline (line 20267: `> 30 * 3600` — 30-hour threshold). Neither validates the bar
DataFrame content itself.
**Impact:** Could drive entries/exits from RSI and BXt signals computed on bars that
are hours stale if a feed thread silently exits. The WS price gate (`_fresh = _ws_age < 5000`)
partially mitigates this for BXt signal confirmation (fail-open, not fail-closed),
but RSI extreme and divergence setups do not require a fresh WS quote to fire.
**Fix (lightweight):** In `_evaluate_symbol`, add a bar age check before strategy logic:
```python
# bot.py:4680 area — add after MIN_BARS guard:
_last_bar_age_sec = (time.time() - signal_df.index[-1].timestamp())
if _last_bar_age_sec > 15 * 60: # no new bar in >15m during active hours
logger.warning("%s bars stale: last bar %ds ago", sym, int(_last_bar_age_sec))
return
```
---
### RISK (carried since 2026-07-16): `_ab_latest_l2` TTL equals loop sleep interval — jitter causes alternating valid/stale snapshots
**File:** `bot.py:20037`
`_ab_live_loop` sleeps `time.sleep(15)`. `_ab_latest_l2` TTL is 15 000 ms.
Sub-millisecond write latency means alternate ticks see `age > 15000` → None.
Root enabler of the P1 `_ab_l2_flip_check` false-fire above.
**Mitigation:** Increase `max_age_ms` to 30 000 or reduce loop sleep to 10s.
---
### RISK (carried since 2026-07-15 — DORMANT, requires `USE_POLYGON_BARS=true`): `_handle_polygon_bar` daily-TF floor formula produces hourly bins for tf ≥ 1440
**File:** `bot.py:3077`
```python
bs = bar_ts.replace(minute=(bar_ts.minute // tf) * tf, second=0, microsecond=0)
# For tf=1440: (minute // 1440) * 1440 = 0 always → floor = current HH:00
# → every 1m bar gets a fresh hourly bucket; ss.bars[1440] grows ×288/day
```
`USE_POLYGON_BARS` not set in dev or prod docker-compose — dormant. Fix when enabling.
---
### RISK (carried since 2026-07-15 — DORMANT, requires `USE_POLYGON_BARS=true`): Polygon bar feed skips bars closed during startup gap
**File:** `bot.py:3147–3153`
On restart during RTH, initialization marks `_poly_bars_last_seen[sym]` as the latest
closed bar, then skips it. Bars closed while the bot was down, before that mark, are
silently dropped. `ss.bars[1]` has a gap at session start.
**Fix when enabling:** Replay from `ss.bars[1].index[-1]` (in-memory watermark) not
from `df_closed.index[-1]` (latest Polygon bar).
---
### RISK (carried since 2026-07-01): VWAP session grouping treats PT-naive bar indices as UTC — session resets at ~03:00 EDT instead of midnight ET
**File:** `core/indicators.py:134`
```python
idx = pd.DatetimeIndex(pd.to_datetime(close.index, utc=True))
session_groups = pd.Series(idx.date, index=close.index)
```
`pd.to_datetime(..., utc=True)` treats PT-naive values as UTC. Session boundary
shifts from midnight ET to 03:00 EDT (= midnight UTC = midnight PT-naive). Overnight
RSI extreme entries get a 3h-shorter VWAP anchor.
---
### RISK (carried since 2026-07-01): Duplicate daily bar in `ss.bars[144