Ulric
Book a call

Eugene, Oregon · one person, whole builds

Case study

Jev Ask: a market question in, a likelihood out

Type a market question in plain English and get a likelihood, a range and the steps behind it. A separate Just for fun page answers silly questions from 162 hand-written cards.

ClientUlric studio product
Year2026
ScopeProduct design, Full-stack development, Quantitative modeling, LLM integration, ASP.NET Core, Angular
Codegithub.com/erichers/jev-ask ↗
Jev Ask: a market question in, a likelihood out
162hand-written fun cards across 9 topics
6fields the optional model must fill, or it falls back
25+parser questions under test
69passing xUnit tests

Why I built it

Jev Odds answers a question once you have filled in a form: ticker, percent, direction, date. Most people do not think in forms. They think in sentences, like "Will NVDA close above 250 by end of month?" I wanted to see if a small app could take that sentence, show me exactly how it read it, and answer with a number instead of a paragraph.

The second reason was to test a pattern I care about. A language model is good at reading a messy sentence. It is not something I want to trust with the math, or to trust at all without checking. So in Jev Ask, the model is optional, its job is small, and its output has to fit a strict shape or it is thrown away.

Like the other Jev apps, this is an educational tool. It is not financial advice and it does not touch money.

What it does

You type a question. The screen shows how it was read as a row of chips: ticker, condition, close or touch, level, and date. You can edit any chip and the answer recomputes. The big number is the likelihood. Under it is a range, a short paragraph, five numbered steps that show the working, and a chart of recent closes with the target drawn across it.

Every answer says which parser ran and whether the prices were live or cached. Recent questions are kept in the browser and in the database, a saved answer has its own link, and there is a PDF brief.

How it's built

The API is ASP.NET Core 8 and the front end is Angular 22, standalone and zoneless, with signals. Data is in SQLite by default or MySQL 5.7 through Pomelo. Chart.js draws the price chart, QuestPDF writes the brief, and three.js draws a path field under the answer that loads only when that view is on screen.

Reading the sentence

The default parser is rule based and needs no key. It looks for a ticker in a fixed order: a dollar ticker like $NVDA, then a company or index name like Nvidia or S&P 500, then a bare uppercase symbol of two to five letters. Words like above, below, drop and rise set the condition. "Touch" or "hit" means a barrier test, and anything else means a close test. A percent is preferred over a dollar level. Dates take the earliest, longest match, so "this Friday," "next Friday," "end of month," "in 10 days" and "Dec 20" all work. If there is no date, the parser uses 30 days out and the answer says so.

The optional model can be a local Ollama model, or the free tiers of OpenRouter, Groq or Gemini. Keys live only in the environment, never in the repo. Whatever the model returns must be one JSON object with six fields: ticker, condition, style, level mode, level and expiry. If any field is missing or out of range, or the call fails, the rule parser runs instead, and the answer says that it fell back.

Making the number

The probability engine assumes zero drift and uses realized volatility on 20, 60 and 252 trading days, with the 60-day window as the point estimate. A close question uses the lognormal formula. A touch question uses the continuous formula with a small shift to the barrier, from a method by Broadie, Glasserman and Kou, so it matches prices that are only checked once a day. The range is the spread across the volatility windows. A Monte Carlo run and a count of past windows sit next to it as checks, and the count is left out when fewer than 30 windows qualify.

The xUnit suite was at 69 passing tests at the last run. It covers more than 25 parser questions, the close and touch formulas, the Monte Carlo check, trading-day counts, the model fallback, the PDF, all 15 bundled tickers, and the fun page.

Just for fun

I also wanted a place for questions that have nothing to do with markets, and I did not want them anywhere near the market parser. Just for fun is a separate route for pop culture, memes, movies, music, sports banter, food, everyday life, space and pets. It never touches the market parser, and it keeps its own history.

Shuffle deals a card from a hand-written bank of 162 questions. Each card has a likelihood, a short reason, a category, and a tag like Base rate, Vibes or Physics says no. One card in the bank asks "Will a cat knock something off a table this week?" It is tagged Base rate, at 72%. If you type your own question, the app looks for a close match in the bank first. If nothing is close, it hashes the wording, so the same question always gets the same number. Every fun answer carries the line "For fun. Not a prediction."

A design review round

Each build went through a design reviewer at 390, 768 and 1440 pixels wide, in light and dark, with reduced and normal motion, against a written rubric.

  • The 3D field on the market side waits for a Rotate press before it takes a drag, so a swipe scrolls the page on a phone. It also no longer turns on its own after the page loads. It holds still until you press Rotate.
  • With WebGL off, the frame shows a still of the same field, with the lime band past the target, and it fills the frame the way the live view does. The first version filled 41 percent of it. The reviewer measured 80 to 84 percent after the fix.
  • On a phone, the ticker and condition chips now sit on a full row of their own.
  • The question box placeholder measured 4.05 to 1 in light mode on phones, under the 4.5 to 1 the rubric asks for at 20 pixels. The fix uses the muted text color at full strength, which measures 6.5 to 1 in light and 7.0 to 1 in dark, with more padding around the composer.

What I learned

The parser needed more care than the math. The formulas are standard and well documented. Reading "Does TSLA touch 420 before Dec 20?" correctly every time, without guessing, took most of the rules and most of the parser tests. Showing the parsed chips on screen mattered more than I expected, because it turns a wrong read into something you can see and fix in one click.

I also found that a strict shape is what makes an optional model safe to use. Once the model's only job was to fill six fields, and anything else fell back to the rules, I stopped worrying about what it might say.

Keeping the fun questions apart from the market questions was also worth it. It keeps the market history clean, and it makes the line between a model of volatility and a joke very clear.

Why this is a Jev app

Jev Ask does not call TypeSafe's Jev model. The optional parser can use a free or local model to read the sentence, but the number always comes from the probability engine. I named it Jev because of what the answer has to look like: a committed probability, the inputs it was based on, and a saved record.

This section is my opinion and my prediction, so I want to label it that way.

When I say Jev decision-making, I mean a model that is asked a typed question and has to commit. It gives a probability and a call, and it is clear about what the call was based on. That answer is logged with the time and the inputs, and later it is scored against what actually happened. Jev is the name TypeSafe gave its first System One model, and it does the first half of that directly. It takes a typed question and returns typed values and probabilities, such as a choice from a list, a score on a rubric, or the probability that a statement is true, instead of a paragraph. The logging and the scoring are the half I build around it.

In the early days of ChatGPT, I felt like I could get a model to give me a number and stand behind it. That was an early capability, and in my experience it faded in the versions that followed: more hedging, more "it depends," fewer committed numbers. I do not know the full reasons for that, and I am not claiming to. It is how it felt from my side of the screen.

My view is that frontier and open model providers will build Jev and TypeSafe style typed probabilistic decision-making into the core of their models. Software needs answers it can branch on, and a typed probability I can score later is more useful to me than a paragraph I have to interpret. TypeSafe and Jev are the clearest version of that idea I have seen so far, and I think it will end up as a standard feature rather than a niche one. That is a prediction, not something I can prove today.

None of this is financial advice. Where I use Jev near markets, it is on a paper trading account with no real money, and I do not publish trading results.

What's next

  • Holidays in the trading-day count. Jev Ask skips weekends but not market holidays, and Jev Odds already has the calendar.
  • Scoring saved answers once their dates pass, so the history shows how the numbers held up.

Tech stack

  • ASP.NET Core 8 Web API
  • Angular standalone components, zoneless, with signals
  • EF Core with SQLite or MySQL
  • A rule parser that needs no key, with an optional local or free-tier model held to a six-field JSON shape
  • Chart.js for the price chart
  • QuestPDF for the brief
  • three.js for the path field
  • A curated 162 card bank with a hash for free text

Repository

The GitHub repository for this app is github.com/erichers/jev-ask.

Likelihood answer with 82 percent
Likelihood answer with 82 percent
Recent questions list on desktop and phone
Recent questions list on desktop and phone
Ask something on desktop and phone
Ask something on desktop and phone
Answer with working steps on desktop and phone
Answer with working steps on desktop and phone
Ask page on three phones
Ask page on three phones
Dark mode ask page
Dark mode ask page

Common questions

Does Jev Ask need an API key?

No. The default parser is rule based and needs no key. A free or local model can be switched on, and anything it returns that does not fit the expected shape falls back to the rule parser.

Is the likelihood a forecast?

No. It is a model of realized volatility with zero drift, shown with its inputs. It is an educational tool and not financial advice.

What is Just for fun?

A separate page for silly questions about pets, movies, food and so on. It never touches the market parser, and every answer says "For fun. Not a prediction."

← All work