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 — exit_flow audit 2026-06-09 — 0P0 6P1 5R
AI verdict
employee
high
· confidence: high
· by internal-exempt
“Sydnee Agent (AI): Sydnee nightly — exit_flow audit 2026-06-09 — 0P0 6P1 5R”
Reasoning: @sydnee.ai is a protected domain — hard exemption
Sydnee nightly — exit_flow audit — 2026-06-09
P0 findings: 0 P1 findings: 6 Risks: 5
- Area: Exit flow (how and when open positions are closed)
- Branch: `dev` (4517516)
- Files scanned: `bot.py` (~18 497 lines), `docs/strategy_decisions.md`, prior exit-flow audits (2026-06-02), `git log --oneline -30`
- Bugs found (P0 / P1): 0 / 6 (1 new, 5 carried)
- Risks noted: 5 (0 new, 5 carried)
Cross-check: `git log --oneline -30` shows one relevant commit since the 2026-06-02 exit-flow audit: `4517516 fix(tv-bxt): scale-in slot count reset + window timer pin + pre-market block`. That commit touches only `_tv_scale_step` (scale-in first-fill logic) and the RTH-only gate — no exit-path code. All 5 carried P1s from 2026-06-02 are confirmed unfixed. 1 new P1 found: TRIM1 has the same 1-share flag-clearing gap as the carried TRIM2 bug.
---
Full report (dev branch): https://github.com/kanex1/sydnee.signals/blob/dev/docs/audit_2026-06-09_exit_flow.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-09 — EXIT FLOW
## Summary
- Area: Exit flow (how and when open positions are closed)
- Branch: `dev` (4517516)
- Files scanned: `bot.py` (~18 497 lines), `docs/strategy_decisions.md`, prior exit-flow audits (2026-06-02), `git log --oneline -30`
- Bugs found (P0 / P1): 0 / 6 (1 new, 5 carried)
- Risks noted: 5 (0 new, 5 carried)
Cross-check: `git log --oneline -30` shows one relevant commit since the 2026-06-02 exit-flow audit: `4517516 fix(tv-bxt): scale-in slot count reset + window timer pin + pre-market block`. That commit touches only `_tv_scale_step` (scale-in first-fill logic) and the RTH-only gate — no exit-path code. All 5 carried P1s from 2026-06-02 are confirmed unfixed. 1 new P1 found: TRIM1 has the same 1-share flag-clearing gap as the carried TRIM2 bug.
---
## Findings
### BUG [P1] (new): TRIM1 `_rsi_force_trim` and `_trimmed` flags never set/cleared for 1-share parents
**File:** `bot.py:5395–5456` (`EXIT 4` TRIM1 block)
**Evidence:**
```python
# bot.py:5395–5407 — TRIM1 condition and guard:
if not hit and not is_trimmed and _trim_hit:
if True:
trim = True
...
trim_shares = t.shares if _flat_full_close else t.shares // 2 # = 0 for 1-share, non-FLAT
...
if trim_shares > 0: # ← guard
...
t._trimmed = True # ← line 5411: inside guard — never set for 1-share
t._rsi_force_trim = False # ← line 5412: inside guard — never cleared for 1-share
self._update_trade_field(t.trade_id,
trimmed_1=True, force_trim_pending=False, ...)
...
# no else branch
```
For a 1-share parent:
- `trim_shares = 1 // 2 = 0` (non-FLAT_EXIT setup)
- Neither `t._trimmed` nor `t._rsi_force_trim` is updated
- `trim = True` is set unconditionally at line 5397
**Concrete cascade for an RSI-forced TRIM1 on 1-share LONG:**
1. RSI(9) ≥ 70 fires: `t._rsi_force_trim = True`, `force_trim_pending=True` written to DB (line 5179-5182)
2. Next bar: `_trim_hit = True` (from force flag, line 5392-5393); `trim_shares = 0`
3. `t._trimmed = False` unchanged → `not is_trimmed = True` → TRIM1 re-fires every bar
4. `t._rsi_force_trim = True` unchanged → loop is permanent; DB `force_trim_pending=True` stale
5. `trim = True` every bar → EXIT 5 (BE) and FIX 1 (trailing stop) both blocked by `not trim` guard (lines 5458-5459 and 5473)
6. Net: no BE move, no trailing stop, no hold log until the original wide stop fires
This is the same structural gap as the carried TRIM2 bug (audit 2026-05-26, still unfixed). Natural price-hit TRIM1 (no force flag) is also affected: `t._trimmed` never set → TRIM1 re-enters every bar while `live_price >= _stored_trim`, silently suppressing all hold/trail logging.
**Impact:** 1-share positions (any odd-lot fill resulting in 1 parent share after trim failures) silently disable the BE stop and trailing stop. DB `force_trim_pending` stays stale through restarts. Activity log shows no hold updates until stop-out. Frequency: any RSI-extreme or BXt-reversal trade that enters at a share count yielding 1 parent share after the first trim fill.
**Fix:** Add an `else` after `if trim_shares > 0:` at `bot.py:5407`:
```python
else:
t._trimmed = True
t._rsi_force_trim = False
self._update_trade_field(t.trade_id,
trimmed_1=True, force_trim_pending=False,
force_trim_reason=None, extreme_since_trim=live_price)
t._extreme_since_trim = live_price
```
---
### BUG [P1] (carried from 2026-06-02): `profit_per_share` uses stale bar close — `_in_profit` gate misroutes RSI/BXt exits when intrabar price is at a loss
**File:** `bot.py:4855` (`profit_per_share` assignment); `bot.py:5122` (`_in_profit` gate)
**Evidence:**
```python
# bot.py:4854-4855 — live_price set but NOT used for profit:
live_price = float(ss.last_price) if ss.last_price else close_price
profit_per_share = (close_price - t.entry_price) * t.direction # ← stale close
# bot.py:5122 — gates trim-ladder vs full-close routing:
_in_profit = profit_per_share > 0
```
When RSI/BXt reversal fires and intrabar price has moved below entry since the last 5m close, `_in_profit = True` (using stale bar close) routes the exit to the trim ladder. The trim child fills at the lower live price, then the BE stop is placed above current price, guaranteeing an immediate stop-out on the runner.
**Fix:** Use `live_price` for the profit gate:
```python
# bot.py:5122 — replace:
_in_profit = profit_per_share > 0
# with:
_in_profit = (live_price - float(t.entry_price)) * t.direction > 0
```
Same fix applies at the BXt reversal `_in_profit` check (same variable, same scope — `bot.py:5271`).
---
### BUG [P1] (carried from 2026-06-02): `_check_stops` defined but never called — intrabar bar-high/low stop check is dead code
**File:** `bot.py:6583` (definition); zero callers in all `.py` files
**Evidence:**
```python
# bot.py:6583 — defined, never called:
def _check_stops(self, trade: Trade, bar) -> None:
if trade.stop_price:
if trade.direction == 1 and bar.low <= trade.stop_price: # ← correct bar-low check
...
```
The 5m exit loop at `bot.py:4991-4995` only checks `close_price` against `stop_price`. A bar that trades through the stop but closes above it never fires. `_check_stops` was intended to fix this using bar high/low, but was never wired in.
**Impact:** Any volatile bar with an intrabar wick through the stop level is missed. Mitigated only when `WS_TICK_EXITS=true` (default off).
**Fix:** Wire the intrabar bar check into `_evaluate_symbol` near the existing `_stop_hit_pending` block using `signal_df["low"].iloc[-1]` / `signal_df["high"].iloc[-1]` already in scope.
---
### BUG [P1] (carried from 2026-05-26): OBV Rule F permanently disabled after in-loss skip
**File:** `bot.py:4936–4943`
**Evidence:**
```python
# bot.py:4921 — in-loss + profit guard path:
if _profit_guard and profit_per_share < 0:
if _loss_exit:
hit = True # OBV_LOSS_EXIT spot-exit
...
elif not getattr(t, '_obv_be_applied', False):
self._log_activity(...) # just logs
t._obv_be_applied = True # ← line 4941: consumed WITHOUT moving stop
...
```
When `OBV_BE_STOP=true`, `RSI_TRIM_PROFIT_GUARD=true`, `OBV_LOSS_EXIT=false` and the position is at a loss when OBV turns adverse: the in-loss skip sets `_obv_be_applied = True` without ever moving the stop. On all subsequent bars Rule F is skipped via the outer guard `not getattr(t, "_obv_be_applied", False)` — even if the trade recovers to profit and a BE tighten would be appropriate.
**Fix:** Remove `t._obv_be_applied = True` (lines 4941-4943) from the in-loss / non-loss-exit path; keep it only in the profit path (line 4947) and in the `OBV_LOSS_EXIT` hit path (trade is closing anyway).
---
### BUG [P1] (carried from 2026-05-26): TRIM2 `_rsi_force_trim2` flag never cleared for 1-share parents
**File:** `bot.py:5337–5371`
**Evidence:**
```python
# bot.py:5337-5345:
if not hit and is_trimmed and not is_trimmed_2 and (_trim2_hit or _force_trim2):
trim = True
trim2_shares = t.shares // 2
if trim2_shares > 0:
t._trimmed_2 = True
t._rsi_force_trim2 = False # ← inside guard — never clears when shares=1
...
# no else branch
```
1-share position leaves `_rsi_force_trim2 = True` and `force_trim2_pending=True` in DB. Every bar re-enters the TRIM2 block, `trim = True`, suppressing the hold log.
**Fix:** Add an `else` after `if trim2_shares > 0:`:
```python
else:
t._trimmed_2 = True
t._rsi_force_trim2 = False
self._update_trade_field(t.trade_id, trimmed_2=True,
force_trim2_pending=False, force_trim_reason=None)
```
---
### BUG [P1] (carried from 2026-05-31): `TV_BXT_TRAIL_AGAINST` default mismatch — live `1.0` vs history endpoint `1.5`
**File:** `bot.py:3774` (live OBV trail); `bot.py:14352` (history replay / stop-analysis endpoint)
**Evidence:**
```python
# bot.py:3774 — live _obv_trail_stop_hit:
agnst = float(os.environ.get("TV_BXT_TRAIL_AGAINST", "1.0"))
# bot.py:14352 — history replay (dashboard /api/trade_obv_trail):
agnst = float(os.environ.get("TV_BXT_TRAIL_AGAINST", "1.5"))
```
When env var is unset, live trail uses `1.0×ATR`; dashboard stop-analysis uses `1.5×ATR`. Operator sees a 50% wider trail in the dashboard than what actually ran.
**Fix:** Change `bot.py:14352` default `"1.5"` → `"1.0"`.
---
### RISK: `_stop_hit_pending` overwrites earlier `hit=True` reason with no `not hit` guard
**File:** `bot.py:5109`
**Evidence:**
```python
# EXIT 0B (HOLD_CAP) correctly guards: `if _hold_cap > 0 and not hit and ...` (line 4970)
# But the stop-loss deferred check has NO guard:
if _stop_hit_pending: # ← line 5109: no `not hit` check
hit, reason = True, f"Stop-loss ${t.stop_price:.2f} · ..." # ← overwrites
```
If `OBV_LOSS_EXIT` fires first (sets `hit=True, reason="OBV rule F..."`), and the same bar's close also hits the stop (`close_price <= stop_price`), `_stop_hit_pending=True` overwrites the exit reason. DB `exit_reason` says "Stop-loss" instead of "OBV rule F." No incorrect close; P&L attribution is wrong.
**Fix:** `if _stop_hit_pending and not hit:` at line 5109.
---
### RISK (carried): Tick exit path (`_tick_exit_step`) has no TRIM2 check — `WS_TICK_EXITS=true` skips the trim2 level
**File:** `bot.py` (`_tick_exit_step` function, ~line 16750)
When `WS_TICK_EXITS=true`: after tick T1 fires (50% trim), the remaining 50% is managed by the next 5m bar. If price reaches target intrabar after T1 but before bar close, TICK TARGET fires → closes the remaining 50% directly, compressing the 4-level ladder into 2 levels. Behavioral divergence from `WS_TICK_EXITS=false` runs.
---
### RISK (carried): 5m-naked OBV trail stop unavailable first 75 min of pre-market
**File:** `bot.py:3769` (`_tv_atr_obv`); `bot.py:4123` (`_eval_bxt_1m_naked`)
OBV trail requires `n >= 15` 5m bars (75 min). 5m-naked entries at/after 04:15 ET have no OBV trail stop until ~05:30 ET. Unlimited loss risk during that window. Note: the 2026-06-08 fix restoring RTH-only for TV-BXt (`TV_BXT_RTH_ONLY`) reduces exposure for TV mode; 5m-naked is unaffected.
---
### RISK (carried): FLAT_EXIT parent closed with empty `exit_reason` in DB
**File:** `bot.py:1319` (`_close_trade_in_store`)
```python
pnl = t.pnl
...
self.db.close_trade(
trade_id=trade_id, exit_price=exit_price,
exit_time=..., pnl=pnl, exit_reason="", # ← always empty
```
`_close_trade_in_store` hard-codes `exit_reason=""`. FLAT_EXIT parent rows (100%-close triggers this path at line 5454) are unclassifiable in SQL exit-type queries. The trim child record has the real reason; the parent does not.
---
### RISK (carried): `trim3` parent-DB comment stale
**File:** `bot.py:8272`
```python
elif trade.trade_id.endswith("_trim3"):
pass # no DB column for trim3 yet — state tracked in-memory
```
`trimmed_3` column was added in commit `a6be962` (2026-04-15). The `pass` is correct (parent's `trimmed_3` is already updated at `bot.py:5302` when the trim is set up — not here), but the comment `"no DB column for trim3 yet"` is false and risks a developer adding a redundant second update to this handler.
---
## OK (checked, working or recently fixed):
- **Scale-in first-fill fix (2026-06-08, `4517516`):** `st["slots_done"] = slot_n` (not reset to 1) and `st["start_ms"] = now_ms` correctly preserve skip count and anchor the 10-min window to first actual fill. TV-BXt closes (`_tv_close`) still pop `_tv_scale_state` on every close path. ✓
- **RTH-only gate tightened to 09:30-16:00 ET:** `570 <= _t_min < 960` in `TV_BXT_RTH_ONLY` path; pre-market entries blocked per 2026-06-08 rollback. ✓
- **`_stop_hit_pending` set on bar-close, not intrabar (confirmed):** lines 4991-4995 use `close_price` correctly for the deferred stop flag. ✓
- **HOLD_CAP `not hit` guard:** `if _hold_cap > 0 and not hit and not getattr(t, '_trimmed_2', Fals