Daily Analysis — Start of Day (global, MCP-only)
This skill replaces the old project-local /sod (formerly at
Journals/.claude/skills/sod/, deferring to Journals/PROMPTS.md). That file and its
markdown-writing sibling files are left in place, unused — this skill does not read or write
any of journal/, metrics/, account/, or PROMPTS.md. The session protocol below is now
owned by this file directly, since nothing else reads PROMPTS.md to keep it in sync anymore.
What still has one source of truth: CLAUDE.md at
/Users/latuconsinafr/Personal/Trading/Journals/CLAUDE.md remains the actual rulebook —
Section numbers referenced below (§3, §5, §6, §7, §8, §9, §15, §16, §19) point there. Read it in
full if it hasn't been read yet this session. trading_rules (the DB table meant to eventually
hold this content structurally) is empty as of 2026-08-18 — porting CLAUDE.md's 21 sections into
structured rows correctly is its own high-stakes task, not something to do casually here. Until
that exists, this file keeps reading CLAUDE.md directly rather than trusting an empty table.
If anything this session suggests a rule should change, per CLAUDE.md §20.14: add it to
CLAUDE.md §21.3 (a short row in the parked-observations table) — do not act on it. Rule
changes belong at quarter boundaries (§13). This is the one legitimate edit this skill makes to
CLAUDE.md itself; nothing else in this file writes to it.
Instruments — resolved live via get_active_instruments, never hardcoded. Call it in Step 2
below and use its result for the rest of this session — do not assume EU/GU/UJ/XAU is still the
active set (CLAUDE.md §2; toggled via pairs.isActive). It returns each active pair's full code
(EURUSD, not the shorthand this file still uses for readability) plus its base/quote currencies
— every other MCP tool's instrument parameter needs the full code, confirmed by an actual
rejected call during this skill's own smoke test (2026-08-18, back when this was a fixed table).
Step 0 — confirm the MCP server is actually reachable
Do this before anything else. There is no markdown fallback anymore — if the MCP server is
down, nothing from this session can be recorded at all. Call get_account_state (cheap, no
side effects) as a connectivity check.
- Succeeds → proceed.
- Fails → stop. Tell the pilot plainly: the
trading-journal MCP server isn't reachable,
likely because the production stack isn't running (just run in webapp/, which builds the
app and brings up the Cloudflare tunnel together). Ask whether to wait while they start it and
retry, or proceed analysis-only with an explicit, repeated warning that nothing said in this
session will be saved anywhere. Never silently proceed as if recording will happen when it
won't — that's the exact hindsight/reconstruction failure mode CLAUDE.md §18 exists to prevent,
just in a new shape.
Step 1 — resolve the date
Use today's system date, unless the pilot gives one explicitly.
Hard guard: refuse any date before today. This skill writes a directional thesis, and a
thesis for a day that already happened is being written with knowledge of what the market
actually did — worse than no record, because it looks genuine. If asked for a past date, say
plainly that SOD cannot run for it, and point to /eod [DATE] instead — reviewing what happened
is legitimate; inventing what would have been thought is not. A future date is fine (pre-planning
ahead of a known gap) but flag that it needs re-confirming against same-day charts before
anything is actually traded on it.
Step 2 — load context via MCP, not files
No account/account_spec.md or account/trading_conventions.md to read — that content now
lives in the DB and is the whole reason those files are being left behind. Call:
get_active_instruments — the active pair set, this account's specs for them, and the
currencies involved. Resolve every instrument/currency reference for the rest of this session
from this result, not from memory of a prior session or from this file's own shorthand table.
get_account_state — balance, sizing phase, cumulative deposited, hard-stop threshold.
get_trading_conventions — the declared breakeven/partial/trailing convention in force.
Required before approving any entry (CLAUDE.md §20.10) — never assume which one is active.
get_trading_rules — the live rulebook values (§3.7, §5, §6, §8, §9, §10, §17). State which
value was used and why when it matters to a verdict.
get_open_positions and get_session_completeness (recent) — continuity context, so
today's read isn't blind to what's already open or how recent sessions went.
get_active_levels — every currently-watching level, so Step 5.2 can check today's price
action against them rather than never looking at what's already on file (added 2026-09-05).
Step 3 — locate today's charts
Charts are filed by when they were captured — today, always — not by which entry they
inform. Check, in order:
charts/[DATE]/ (flat) — the normal case, one capture serving both SOD and EOD if this
runs inside /evening.
charts/[DATE]/sod/ — if SOD and EOD are being captured separately this session.
- All required found (D1/H4/M15 × every instrument from Step 2's
get_active_instruments) →
read them directly, don't ask the pilot to re-attach anything.
- Some found, some missing → name exactly which are missing, ask only for those.
- None found, and none pasted this turn → ask the pilot to paste the clean charts for D1/H4/M15
× every active instrument.
Pasted images resolve to a real local path when Claude Code and the trading.db/webapp are on
the same machine (confirmed empirically 2026-08-18) —
attach_chart in Step 6 uses that path
directly. If Claude Code is running on a different machine than the one hosting the MCP
server, a pasted image's local path won't be readable by the server — if attach_chart fails
for this reason, say so plainly rather than silently skipping the attachment.
- Annotated versions also present → set them aside. Read the clean charts first and
independently, before looking at annotated ones or the pilot's stated thesis — this ordering
is deliberate (see Step 5.1); skipping it means anchoring to the pilot's markup instead of
forming an independent read.
1H capture stays optional, separate from the required 12 — not a §2 change. CLAUDE.md §2's
daily-reviewed timeframes (D1/H4/M15) are unaffected and stay exactly as written. If a 1H clean
chart per instrument happens to be available (charts/[DATE]/{SYMBOL}H1.png, matching the
existing {SYMBOL}Daily/H4/M15.png convention), read it and call write_technical_score for it
too (Step 6). Do not ask the pilot to capture 1H specifically — D1/H4/M15 are the only charts
this session actually requires; 1H is a bonus if it's already there, not a new ask.
Step 4 — get the pilot's thesis
Ask once, plainly: "What's your thesis for each instrument today?" — and wait. Do not
proceed without it and do not offer one first. CLAUDE.md §1 is absolute: Claude never
originates the first directional call, for any instrument, ever.
Step 5 — run the analysis, in this exact order
- Using ONLY the clean charts, state an independent structural read per instrument (D1
structure → H4 confirmation → M15 timing) — before reacting to the pilot's thesis or any
annotated chart. For every level named, state WHERE PRICE PREVIOUSLY TURNED there (date +
wick) — CLAUDE.md §3.3's validation test. The date is exact, counted from the nearest labeled
gridline — never "approx," and a sparsely-labeled chart is never a reason to skip naming one.
Apply the same counting effort to every instrument this session — do not verify one more
carefully than the others. But decide per instrument, not for the session as a whole: if
one instrument's turn can't be dated, that one is unvalidated — it does not mean skipping
every other instrument that can be dated. Partial coverage across the session is the normal,
correct outcome, not a fallback. A stated tolerance ("±1-2 days") is not exact and does not
pass; a level that can't clear the same rigor used elsewhere this session doesn't get written
with a hedge, it doesn't get written — for that instrument only. Do this by reading the image
and counting candles — never by
writing or running a script, pixel-measurement tool, or any automated axis calibration; that's
a fragile detour, not extra rigor, and a bug in one is never a reason to write zero levels
instead. If it can't be named, call it a price, not a level.
Note volume where it confirms or contradicts a break, rejection candle, or trend (§3.10,
observational, not pass/fail).
- Check today's read against
get_active_levels's existing watching levels for this
instrument (added 2026-09-05). If price has actually traded through a level, or the
structural thesis it was based on has broken (a close beyond it, a confirmed break of the
swing structure it came from), note it for resolve_level in Step 6 — triggered for the
former, invalidated for the latter. A level that's simply gone stale (superseded by a
tighter/more recent zone, or just old enough it's no longer worth watching) also gets
resolve_level'd with stale, not left to accumulate forever. Do not resolve a level just
because price is near it — only an actual trade-through or a confirmed structural break
counts, same rigor as never inventing a level in the first place.
- Compare against the pilot's thesis (and annotated charts, if attached). Apply the full §3
checklist — support, challenge, or flag gaps. Explicitly check the pilot's levels against the
same standard: prior turn named, zone width within the §3.6 max, and whether the target is the
FIRST obstacle or a later one (§3.7).
- Run today's fundamental digest (§4): calendar events, currency strength 0–10 for each non-metal
currency in Step 2's active-instrument set, risk-sentiment read for each metal in it. §19
sources only — release times/dates from the issuing institution, never a summary article. State
times in WIB / server / ET.
- Apply correlation/clustering (§5), event-risk timing (§6), and the conflict-resolution table
(§7).
- Give a verdict per instrument: enter now / pending limit-stop order / wait for [condition] /
stand aside / skipped — with reasoning.
SKIPPED needs a stated reason; there's no
NOT_ANALYZED case here since every active instrument always gets some verdict in normal
operation.
- If wait/stand-aside: the hypothetical gets logged live in Step 6, not reconstructed later.
Where a setup fails §3.7, it gets logged twice — once at the wanted target, once at the
actual obstacle (§16).
- If entering now, in-session: confirm the DB-configured minimum R:R (
get_trading_rules,
§3.7), check drawdown circuit breakers (§9), size per §8, state the management convention up
front. If entering later, outside this session (the normal case), point to the Pre-Trade
Check per Step 7 below — the record must exist before the click, not after.
Step 6 — write the session through MCP (the only write path)
No markdown, no "additive" fallback — this is the record. If any call in this list fails
partway through, stop and report exactly which calls succeeded and which didn't, rather than
silently treating the session as fully recorded. Never invent values to fill an argument — every
call here uses values that actually came out of Step 5.
write_daily_analysis — once per instrument, every instrument in the active set, every
day, including a SKIPPED verdict with a skipReason if one was deliberately not reviewed.
write_fundamental_digest — once per non-metal currency in the active set.
write_risk_sentiment — once per metal currency in the active set (different scale from
currency strength — don't conflate the two calls).
write_calendar_event — for each relevant event surfaced this session. Leave timeUtc
unset and say so if it isn't verified against a primary source.
write_hypothetical — for any wait/stand-aside verdict, live. Double-log per §16 where a
setup failed §3.7.
write_level — for any level named today that clears §3.3's validation bar, at whichever
timeframe (D1/H4/M15) it was actually read on. As of 2026-08-30 this upserts by matching
pair+timeframe+type+overlapping price range against an existing watching level — a
re-confirmation merges its prior turns into the existing row instead of duplicating it, so there's
no need to manually check get_active_levels first just to avoid a duplicate. A materially
different zone (non-overlapping range) still inserts as its own row, which is correct — multiple
simultaneous support/resistance levels at one timeframe are expected, not an error.
resolve_level — for any level flagged in Step 5.2 as triggered, invalidated, or stale
(added 2026-09-05). Requires the level's real id — use the one get_active_levels (Step 2)
returned, never guess it. A level not flagged in Step 5.2 gets no call here; resolving levels
speculatively (price merely near one, not actually through it) is the same error class as
inventing a level that was never validated.
attach_chart — once per screenshot actually read this session (D1/H4/M15 × every active
instrument), by the path it was read from in Step 3. Never re-paste an image just to attach it.
If the path isn't readable by the MCP server (cross-machine case, see Step 3), say so rather
than silently skipping.
write_technical_score — once per instrument per timeframe actually read in Step 5.1 (D1,
H4, M15 — every active instrument; plus 1H if it happened to be captured). This is not new
analysis — it's the same structural read from Step 5.1, translated into a -100..100 number
(fundamentals are computed server-side, never passed in). Rough band alignment with the
heatmap's own labels: ≥50 Strong Bullish, 20-49 Bullish, -19..19 Neutral, -50..-21 Bearish,
≤-50 Strong Bearish — direction and conviction from the actual read, not a fixed formula.
Never call this for a pair not actually charted this session — the whole point is
replacing fabricated placeholder scores with real ones, not adding new fabricated ones for
pairs outside the active set (get_active_instruments — the wider pairs catalogue is not
in scope just because it exists).
mark_session — sodDone: true for today's date.
Step 7 — the Pre-Trade Check
If any verdict is "enter now" or produces a level to watch for later entry, point the pilot to
the webapp's /trades/new (https://trading.latuconsinafr.com/trades/new if the tunnel is
up, otherwise whatever local URL is reachable this session) — it runs the same §15/§9 gate,
computes R:R and lot size live, and writes a real OPEN trade plus the compliance checklist
snapshot when submitted.
open_trade (the MCP tool) is import/backfill only — never call it to represent a live entry.
If asked to "record" or "log" a trade the pilot says they just placed, decline and point to
/trades/new instead. This is a settled decision (2026-08-18), not a judgment call to re-litigate
per session.
1---2name: sod3description: Run the Start-of-Day analysis and verdict session for the trading journal (CLAUDE.md Section 11, at /Users/latuconsinafr/Personal/Trading/Journals/CLAUDE.md). Global, MCP-only — writes exclusively to the trading-journal MCP server, no markdown output. Auto-detects today's date, asks for the pilot's thesis, then runs the full daily protocol. Invoke every trading morning.4---56# Daily Analysis — Start of Day (global, MCP-only)78**This skill replaces the old project-local `/sod`** (formerly at9`Journals/.claude/skills/sod/`, deferring to `Journals/PROMPTS.md`). That file and its10markdown-writing sibling files are left in place, unused — this skill does not read or write11any of `journal/`, `metrics/`, `account/`, or `PROMPTS.md`. The session protocol below is now12owned by this file directly, since nothing else reads `PROMPTS.md` to keep it in sync anymore.1314**What still has one source of truth:** `CLAUDE.md` at15`/Users/latuconsinafr/Personal/Trading/Journals/CLAUDE.md` remains the actual rulebook —16Section numbers referenced below (§3, §5, §6, §7, §8, §9, §15, §16, §19) point there. Read it in17full if it hasn't been read yet this session. `trading_rules` (the DB table meant to eventually18hold this content structurally) is empty as of 2026-08-18 — porting CLAUDE.md's 21 sections into19structured rows correctly is its own high-stakes task, not something to do casually here. Until20that exists, this file keeps reading CLAUDE.md directly rather than trusting an empty table.2122**If anything this session suggests a rule should change**, per CLAUDE.md §20.14: add it to23CLAUDE.md §21.3 (a short row in the parked-observations table) — **do not act on it.** Rule24changes belong at quarter boundaries (§13). This is the one legitimate edit this skill makes to25CLAUDE.md itself; nothing else in this file writes to it.2627**Instruments — resolved live via `get_active_instruments`, never hardcoded.** Call it in Step 228below and use its result for the rest of this session — do not assume EU/GU/UJ/XAU is still the29active set (CLAUDE.md §2; toggled via `pairs.isActive`). It returns each active pair's full code30(`EURUSD`, not the shorthand this file still uses for readability) plus its base/quote currencies31— every other MCP tool's `instrument` parameter needs the full code, confirmed by an actual32rejected call during this skill's own smoke test (2026-08-18, back when this was a fixed table).3334## Step 0 — confirm the MCP server is actually reachable3536**Do this before anything else.** There is no markdown fallback anymore — if the MCP server is37down, nothing from this session can be recorded at all. Call `get_account_state` (cheap, no38side effects) as a connectivity check.3940- **Succeeds** → proceed.41- **Fails** → stop. Tell the pilot plainly: the `trading-journal` MCP server isn't reachable,42 likely because the production stack isn't running (`just run` in `webapp/`, which builds the43 app and brings up the Cloudflare tunnel together). Ask whether to wait while they start it and44 retry, or proceed analysis-only with an explicit, repeated warning that nothing said in this45 session will be saved anywhere. Never silently proceed as if recording will happen when it46 won't — that's the exact hindsight/reconstruction failure mode CLAUDE.md §18 exists to prevent,47 just in a new shape.4849## Step 1 — resolve the date5051Use today's system date, unless the pilot gives one explicitly.5253**Hard guard: refuse any date before today.** This skill writes a directional thesis, and a54thesis for a day that already happened is being written with knowledge of what the market55actually did — worse than no record, because it looks genuine. If asked for a past date, say56plainly that SOD cannot run for it, and point to `/eod [DATE]` instead — reviewing what happened57is legitimate; inventing what would have been thought is not. A future date is fine (pre-planning58ahead of a known gap) but flag that it needs re-confirming against same-day charts before59anything is actually traded on it.6061## Step 2 — load context via MCP, not files6263No `account/account_spec.md` or `account/trading_conventions.md` to read — that content now64lives in the DB and is the whole reason those files are being left behind. Call:6566- **`get_active_instruments`** — the active pair set, this account's specs for them, and the67 currencies involved. Resolve every instrument/currency reference for the rest of this session68 from this result, not from memory of a prior session or from this file's own shorthand table.69- **`get_account_state`** — balance, sizing phase, cumulative deposited, hard-stop threshold.70- **`get_trading_conventions`** — the declared breakeven/partial/trailing convention in force.71 Required before approving any entry (CLAUDE.md §20.10) — never assume which one is active.72- **`get_trading_rules`** — the live rulebook values (§3.7, §5, §6, §8, §9, §10, §17). State which73 value was used and why when it matters to a verdict.74- **`get_open_positions`** and **`get_session_completeness`** (recent) — continuity context, so75 today's read isn't blind to what's already open or how recent sessions went.76- **`get_active_levels`** — every currently-`watching` level, so Step 5.2 can check today's price77 action against them rather than never looking at what's already on file (added 2026-09-05).7879## Step 3 — locate today's charts8081Charts are filed by **when they were captured** — today, always — not by which entry they82inform. Check, in order:83841. **`charts/[DATE]/`** (flat) — the normal case, one capture serving both SOD and EOD if this85 runs inside `/evening`.862. **`charts/[DATE]/sod/`** — if SOD and EOD are being captured separately this session.8788- **All required found** (D1/H4/M15 × every instrument from Step 2's `get_active_instruments`) →89 read them directly, don't ask the pilot to re-attach anything.90- **Some found, some missing** → name exactly which are missing, ask only for those.91- **None found, and none pasted this turn** → ask the pilot to paste the clean charts for D1/H4/M1592 × every active instrument.93 Pasted images resolve to a real local path when Claude Code and the trading.db/webapp are on94 the same machine (confirmed empirically 2026-08-18) — `attach_chart` in Step 6 uses that path95 directly. **If Claude Code is running on a different machine than the one hosting the MCP96 server**, a pasted image's local path won't be readable by the server — if `attach_chart` fails97 for this reason, say so plainly rather than silently skipping the attachment.98- **Annotated versions also present** → set them aside. Read the clean charts first and99 independently, before looking at annotated ones or the pilot's stated thesis — this ordering100 is deliberate (see Step 5.1); skipping it means anchoring to the pilot's markup instead of101 forming an independent read.102103**1H capture stays optional, separate from the required 12 — not a §2 change.** CLAUDE.md §2's104daily-reviewed timeframes (D1/H4/M15) are unaffected and stay exactly as written. If a 1H clean105chart per instrument happens to be available (`charts/[DATE]/{SYMBOL}H1.png`, matching the106existing `{SYMBOL}Daily/H4/M15.png` convention), read it and call `write_technical_score` for it107too (Step 6). **Do not ask the pilot to capture 1H specifically** — D1/H4/M15 are the only charts108this session actually requires; 1H is a bonus if it's already there, not a new ask.109110## Step 4 — get the pilot's thesis111112Ask once, plainly: *"What's your thesis for each instrument today?"* — and wait. **Do not113proceed without it and do not offer one first.** CLAUDE.md §1 is absolute: Claude never114originates the first directional call, for any instrument, ever.115116## Step 5 — run the analysis, in this exact order1171181. Using ONLY the clean charts, state an independent structural read per instrument (D1119 structure → H4 confirmation → M15 timing) — **before** reacting to the pilot's thesis or any120 annotated chart. For every level named, state WHERE PRICE PREVIOUSLY TURNED there (date +121 wick) — CLAUDE.md §3.3's validation test. **The date is exact, counted from the nearest labeled122 gridline — never "approx," and a sparsely-labeled chart is never a reason to skip naming one.123 Apply the same counting *effort* to every instrument this session — do not verify one more124 carefully than the others. But decide *per instrument, not for the session as a whole*: if125 one instrument's turn can't be dated, that one is unvalidated — it does not mean skipping126 every other instrument that *can* be dated. Partial coverage across the session is the normal,127 correct outcome, not a fallback. A stated tolerance ("±1-2 days") is not exact and does not128 pass; a level that can't clear the same rigor used elsewhere this session doesn't get written129 with a hedge, it doesn't get written — for that instrument only. Do this by reading the image130 and counting candles — never by131 writing or running a script, pixel-measurement tool, or any automated axis calibration; that's132 a fragile detour, not extra rigor, and a bug in one is never a reason to write zero levels133 instead.** If it can't be named, call it a price, not a level.134 Note volume where it confirms or contradicts a break, rejection candle, or trend (§3.10,135 observational, not pass/fail).1362. **Check today's read against `get_active_levels`'s existing `watching` levels for this137 instrument (added 2026-09-05).** If price has actually traded through a level, or the138 structural thesis it was based on has broken (a close beyond it, a confirmed break of the139 swing structure it came from), note it for `resolve_level` in Step 6 — `triggered` for the140 former, `invalidated` for the latter. A level that's simply gone stale (superseded by a141 tighter/more recent zone, or just old enough it's no longer worth watching) also gets142 `resolve_level`'d with `stale`, not left to accumulate forever. Do not resolve a level just143 because price is *near* it — only an actual trade-through or a confirmed structural break144 counts, same rigor as never inventing a level in the first place.1453. Compare against the pilot's thesis (and annotated charts, if attached). Apply the full §3146 checklist — support, challenge, or flag gaps. Explicitly check the pilot's levels against the147 same standard: prior turn named, zone width within the §3.6 max, and whether the target is the148 FIRST obstacle or a later one (§3.7).1494. Run today's fundamental digest (§4): calendar events, currency strength 0–10 for each non-metal150 currency in Step 2's active-instrument set, risk-sentiment read for each metal in it. §19151 sources only — release times/dates from the issuing institution, never a summary article. State152 times in WIB / server / ET.1535. Apply correlation/clustering (§5), event-risk timing (§6), and the conflict-resolution table154 (§7).1556. Give a verdict per instrument: enter now / pending limit-stop order / wait for [condition] /156 stand aside / skipped — with reasoning. `SKIPPED` needs a stated reason; there's no157 `NOT_ANALYZED` case here since every active instrument always gets *some* verdict in normal158 operation.1597. If wait/stand-aside: the hypothetical gets logged live in Step 6, not reconstructed later.160 Where a setup fails §3.7, it gets logged **twice** — once at the wanted target, once at the161 actual obstacle (§16).1628. If entering now, in-session: confirm the DB-configured minimum R:R (`get_trading_rules`,163 §3.7), check drawdown circuit breakers (§9), size per §8, state the management convention up164 front. If entering **later**, outside this session (the normal case), point to the Pre-Trade165 Check per Step 7 below — the record must exist before the click, not after.166167## Step 6 — write the session through MCP (the only write path)168169**No markdown, no "additive" fallback — this is the record.** If any call in this list fails170partway through, stop and report exactly which calls succeeded and which didn't, rather than171silently treating the session as fully recorded. Never invent values to fill an argument — every172call here uses values that actually came out of Step 5.1731741. **`write_daily_analysis`** — once per instrument, every instrument in the active set, every175 day, including a `SKIPPED` verdict with a `skipReason` if one was deliberately not reviewed.1762. **`write_fundamental_digest`** — once per non-metal currency in the active set.1773. **`write_risk_sentiment`** — once per metal currency in the active set (different scale from178 currency strength — don't conflate the two calls).1794. **`write_calendar_event`** — for each relevant event surfaced this session. Leave `timeUtc`180 unset and say so if it isn't verified against a primary source.1815. **`write_hypothetical`** — for any wait/stand-aside verdict, live. Double-log per §16 where a182 setup failed §3.7.1836. **`write_level`** — for any level named today that clears §3.3's validation bar, at whichever184 timeframe (D1/H4/M15) it was actually read on. As of 2026-08-30 this upserts by matching185 pair+timeframe+type+overlapping price range against an existing `watching` level — a186 re-confirmation merges its prior turns into the existing row instead of duplicating it, so there's187 no need to manually check `get_active_levels` first just to avoid a duplicate. A materially188 different zone (non-overlapping range) still inserts as its own row, which is correct — multiple189 simultaneous support/resistance levels at one timeframe are expected, not an error.1907. **`resolve_level`** — for any level flagged in Step 5.2 as triggered, invalidated, or stale191 (added 2026-09-05). Requires the level's real `id` — use the one `get_active_levels` (Step 2)192 returned, never guess it. A level not flagged in Step 5.2 gets no call here; resolving levels193 speculatively (price merely near one, not actually through it) is the same error class as194 inventing a level that was never validated.1958. **`attach_chart`** — once per screenshot actually read this session (D1/H4/M15 × every active196 instrument), by the path it was read from in Step 3. Never re-paste an image just to attach it.197 If the path isn't readable by the MCP server (cross-machine case, see Step 3), say so rather198 than silently skipping.1999. **`write_technical_score`** — once per instrument per timeframe actually read in Step 5.1 (D1,200 H4, M15 — every active instrument; plus 1H if it happened to be captured). This is not new201 analysis — it's the same structural read from Step 5.1, translated into a -100..100 number202 (fundamentals are computed server-side, never passed in). Rough band alignment with the203 heatmap's own labels: ≥50 Strong Bullish, 20-49 Bullish, -19..19 Neutral, -50..-21 Bearish,204 ≤-50 Strong Bearish — direction and conviction from the actual read, not a fixed formula.205 **Never call this for a pair not actually charted this session** — the whole point is206 replacing fabricated placeholder scores with real ones, not adding new fabricated ones for207 pairs outside the active set (`get_active_instruments` — the wider `pairs` catalogue is not208 in scope just because it exists).20910. **`mark_session`** — `sodDone: true` for today's date.210211## Step 7 — the Pre-Trade Check212213If any verdict is "enter now" or produces a level to watch for later entry, point the pilot to214the webapp's **`/trades/new`** (`https://trading.latuconsinafr.com/trades/new` if the tunnel is215up, otherwise whatever local URL is reachable this session) — it runs the same §15/§9 gate,216computes R:R and lot size live, and writes a real `OPEN` trade plus the compliance checklist217snapshot when submitted.218219**`open_trade` (the MCP tool) is import/backfill only — never call it to represent a live entry.**220If asked to "record" or "log" a trade the pilot says they just placed, decline and point to221`/trades/new` instead. This is a settled decision (2026-08-18), not a judgment call to re-litigate222per session.