cd /news/ai-agents/jev-assisted-llm-trading · home topics ai-agents article
[ARTICLE · art-135318] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=· neutral

JEV assisted LLM Trading

A developer built a Python-based shadow grading harness, shadow.py, that uses TypeSafe's text-only JEV model (jev-latest) to audit the reasoning behind hourly vision-model forex trading decisions on funded prop accounts. The harness, gated behind a SHADOW_MODE flag that is a no-op when unset, logs each decision with a sha256 prompt hash and records binary pass/fail verdicts on whether the model's stated thesis is coherent with its directional call, then attaches trade outcomes such as EXECUTED or FAILED. The developer notes a prior $10k account blew through its max drawdown on September 9, and the fleet now runs two $100k accounts as separate instances.

by read6 min views1 publishedSep 20, 2026

Every hour, on the hour, a vision model looks at three forex charts and decides whether our bot should buy, sell, or sit out. It has been doing this with real money since May. As of last Saturday, something finally grades its reasoning.

This post is about the grader.

It's a Python script called gemini_snap_flash. Once an hour it sends a one-minute candlestick chart plus daily and weekly context images to Gemini, gets back UP or DOWN and a one-line thesis, and trades EURUSD, GBPUSD, or USDJPY through MT5 on funded prop accounts. One position per pair, fixed stop and take-profit, and hard rails around it: 2% daily loss cap, 0.6% daily profit cap, and an external watchdog that kills the process after four losses in a row.

The rails matter. The first $10k account blew through its max drawdown on September 9 and is gone. The fleet is two $100k accounts now, run as separate instances (deepseek 4 flash, gemini flash 3.8) with separate state.

Here's the part most AI-trading posts skip. The bot already logs a lot. signal_log.csv has every decision, executed or skipped, with the model's reasoning attached. trade_analysis.csv has every close with MFE/MAE in pips and R-multiples. What nothing had was a check on the decision itself: does the thesis actually argue for the direction the model picked? When the account died, I could read every trade and every excuse, and none of it told me whether the reasoning was any good.

JEV is TypeSafe's System-One model (jev-latest), served at api.typesafe.ai/v1/systemone. It's text-only. No vision, no market opinions. You POST it a "state" string plus a set of questions, each with instructions and pass/fail criteria, and it returns structured verdicts:

{
  "state": "<the thing being judged>",
  "model": "jev-latest",
  "questions": {
    "shadow_direction_consistency": {
      "type": "noul",
      "instructions": "Based only on the provided state (a recorded hourly vision decision for a live FX scalper), is the recorded directional call a clear, self-consistent directional commitment coherent with its own thesis?",
      "criteria": {
        "true": "The recorded direction is explicit (UP or DOWN) and the recorded thesis is coherent with and supports it.",
        "false": "The direction is ambiguous, contradicts the thesis, or no clear directional commitment is recorded."
      }
    }
  }
}

The shape isn't an accident. A noul question is a pass/fail check the model answers one way against criteria you wrote — not an open-ended essay. That's what makes the verdict usable as a watchdog: it stays binary and countable, so you can line thousands of them up against the trades they judged and watch the incoherence rate move. An essay grader couldn't do that; it would drown you in prose and give you nothing to plot.

So it's a proofreader, not a fortune teller. It can't tell you whether UP is right about EURUSD. It can tell you when UP arrives with a thesis that quietly argues DOWN.

The new file is shadow.py, about 430 lines, plus tests. The design has one hard rule: the trading path must not know it exists unless we say so.

Everything is gated behind SHADOW_MODE=1. When that's unset, the harness is a complete no-op; the only cost on the hot path is a single os.getenv() call, and the tests assert that zero network calls happen. When it's on, for every hourly vision decision the harness:

shadow_out/<instance>/<timestamp>/, and records a sha256 of the prompt text for later lookup. shadow_log.jsonl, including the JEV verdict and its latency. A little later, an attach_outcome() call patches the most recent unfinalized line for that pair with what actually happened: EXECUTED, FAILED, or ORDER_FAILED, plus the ticket. It only touches lines written in the last 15 minutes, so a slow hourly cycle can't corrupt an older decision's record.

Each instance writes to its own log, so the fleet's accounts never mix.

Worth saying plainly: SHADOW_MODE is not set in any launch config yet, so zero shadow calls have happened in production. The dashboard probe ledger shows nine calls, all from us poking at the API while building the plugin. The harness is new and the tests are new, and we want a few market-open cycles of confidence before turning on a collector that sits in the decision path.

Three questions, in order of interest.

First, the big one: does coherence predict money? Every verdict lands in the same record as the real action and, downstream, the real P&L. If incoherent trades lose measurably more often than coherent ones, JEV graduates from observer to entry filter, and we skip or downsize flagged decisions. If it doesn't, we drop it. That's the point of measuring instead of believing.

How a verdict gets scored is fixed before the first data point. The pass/fail bar is pre-registered in code — minimum sample sizes, a minimum counterfactual edge, a ceiling on JEV errors — and the backend and the dashboard banner read the same constants, so the goalposts can't move after the data arrives. The edge itself is computed counterfactually: on rows where JEV withholds endorsement, we flip the sign of what the vision-side trade actually realized. That's a mirror approximation, not a P&L replay, and it's labelled as one; orders that never resolved are counted separately, never scored as zero. And if JEV's disagreements turn out to correlate with winners, the shadow signal dies first.

Second, drift detection. The bot retries Gemini up to six times with exponential backoff, and we've swapped models before (3.6-flash to 3.8-flash in Sept). Degraded or fallback responses usually get sloppier before they get unprofitable. A rise in inconsistent verdicts is a cheap alarm — a shadow call is text-only, input-only pricing, a fraction of a cent per decision, and every record carries the JEV latency and error status, so degradation shows up in the record itself before the drawdown alert does.

Third, model comparison. Since the harness records each prompt's hash and the decision but stays agnostic about which model produced them, the same record can score an OpenRouter alternative against Gemini on identical charts. Evidence beats vibes when picking a model.

The limits are real and worth naming. JEV sees the text of the decision, never the chart pixels, so it audits self-consistency only. It will happily bless a confident, well-written, wrong call. It evaluates after the fact, so today it can't stop a trade, which is deliberate: any gating step is a later change with its own risk to review. And it's one question right now. Coverage is only as good as the question set, and one question is a start, not a panel. The API shape makes a panel cheap, though: several independent pass/fail checks can ride in a single request and get combined in code, and our dashboard probe already does that. Adding questions to the harness is a config change, not a rewrite.

The whole thing is built to answer one question, and the answer is allowed to be no. If coherent trades don't make more money than incoherent ones, JEV gets dropped and we've lost a few cents a decision and a couple of weeks. If they do, the auditor stops being a proofreader and becomes a filter. Either way the data decides, and the bar was written before the first verdict landed. That's the part I'm actually proud of — not the harness, the willingness to let it be wrong.

── more in #ai-agents 4 stories · sorted by recency
── more on @typesafe 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/jev-assisted-llm-tra…] indexed:0 read:6min 2026-09-20 ·