Scoring a 'hold' from daily_stock_analysis — the four price levels that only hold together as a counterfactual
daily_stock_analysis called NVDA a hold. I placed that decision as a real order without touching the account. The market was closed, so the verdict came back un
Scoring a 'hold' from daily_stock_analysis — the four price levels that only hold together as a counterfactualYou've finished this article successfully if you can take one hold from your own tool and move its price levels into two counterfactual orders — long and short — without inventing a single number. And, for US equities, check the session first.
| What this does | At the moment a tool says "don't buy now", places the order that buys now and the order that sells now, and carries both to completion without touching the account |
| Who it's for | Anyone whose tool emits price levels alongside its verdict and has never checked whether those levels hold together as an order |
| Who it isn't for | Anyone trying to measure US equities during Korean daylight hours. Closed means unmeasured — and that is half of this article |
| What you end up with | A comparison showing exactly where the tool's four levels stand up and where they collapse, plus a recipe that checks the session and stops on its own |
| Cost | No code cost · no model cost · a weltiq pro account |
| Time / difficulty | 20 minutes if you already have the tool's records · medium (curl, JSON) |
| Relationship to weltiq | This whole article is that — it's a procedure piece, so there's no separate integration section |
| Test environment / date | 2026-09-28 (KST) · isolated server, synthetic quotes · US equities closed (section 5 states the limits plainly) |
| Disclosure | The author is paid by weltiq for this series. The main verdict came back unmeasured, and rather than hide that I made it part of the article |
The human-side lines are real commands rewritten as dialogue; the outputs are measured and the numbers are untouched.
1. The blank this tool kept leaving
I ran daily_stock_analysis in part 25. Its signature output is one verdict plus four price levels. Feed it NVDA and you get this (raw/levels-verbatim.txt, batch run 1):
symbol: NVDA
decision_type: hold operation_advice: 관망 confidence_level: 중간
ideal_buy: 219.01 secondary_buy: 219.16 stop_loss: 218.9 take_profit: 230.0
The NVDA decision dashboard. 227.38 dollars at the top, strategy "hold", trend "sideways", and four price cards below. Look at the fact that **the verdict and the four levels sit on the same screen** — this tool says "don't buy" and hands you a price to buy at in the same breath
It shows its working too (RUN-LOG.md:123): close 227.38 · MA5 219.01 · MA20 219.36 · gap +3.82% · MACD DIF 1.4828 < DEA 1.5377 · resistance 234.50. And five independent runs all came back hold (RUN-LOG.md:125) — this is not a wobbly verdict.
The four price cards, enlarged. The ideal-buy card explains that "the trend is inverted and this price is below MA20, so it is not an order price". **The tool is telling you itself that this number is not an order right now** — that one line is the whole of section 2
Those four levels don't hold together on transfer
In the earlier transfer check (part 3) I pushed the four levels straight into an order. This is what happened.
| Field | On transfer |
|---|---|
stop_loss 218.90 |
goes in |
take_profit 230.00 |
goes in |
ideal_buy 219.01 |
no field for it — a trial order has no entry-condition slot |
secondary_buy 219.16 |
no field for it |
Half of the tool's signature output is dropped. And the surviving half sits oddly: ideal_buy 219.01 and stop_loss 218.90 are 0.05% apart. Buy at 219.01, stop at 218.90, and your stop distance is 0.05%. In run 2, the stop (219.36) came out above the buy price (219.01) (docs/tutorials/a/25-daily-stock-analysis.md:184).
A side finding: send that inverted pair anyway and you get 201. The contract only checks take_profit > stop_loss. It does not catch contradictions with the entry price.
That's the blank. The verdict is the same five times out of five, nobody has measured whether it was right, and the levels shipped with it fall apart when moved into an order.
2. Why this stayed empty
The scorecard for "decided not to buy" has been missing for a simple reason.
To measure it you have to actually buy, and buying moves the account. Capital gets tied up, the loss budget gets eaten, and the result lands in your performance numbers. The act of measuring damages the thing being measured.
This tool makes it especially stark. To measure the hold you have to buy at 227.38 — the exact price the tool told you not to buy at. Nobody does that with a live account.
The trades you decided not to take get a scorecard too. Without your account moving.
A trial order carries that judgment to completion on a separate ledger that never touches your balance, P&L, loss limits or performance totals.
And this is where the four levels find their places
This is the heart of the piece.
On transfer, ideal_buy 219.01 is the entry. Put it there and the 218.90 stop sits 0.05% away, and in run 2 it inverts outright. The set doesn't stand up.
In a counterfactual the entry is the current price. You don't wait for the 219.01 the tool asked for; you buy now. The moment you do, the arrangement changes.
Transfer (entry = ideal_buy 219.01) |
Counterfactual (entry = current 227.30) | |
|---|---|---|
stop_loss 218.90 |
0.05% from entry — barely a stop | below entry — a stop, properly |
take_profit 230.00 |
+5.0% from entry | above entry — a target, properly |
run 2 stop_loss 219.36 |
above the buy price — inverted | below entry — no problem |
| Does the set stand up | no | yes |
The same numbers are unusable on transfer and usable as a counterfactual. The tool didn't emit bad values; it emitted parts for a wait-for-the-dip order, and those parts don't fit the buy-now order. Move the entry to the current price and they find their places.
3. The recipe — the thing that actually runs
The recipe is here: 08-trial-order-daily-stock-analysis-wait.sh. Five steps.
| Step | What |
|---|---|
| ⓪ session | GET /v1/capabilities to see whether us-equity is open. If it's closed, stop |
| ① plant | One long and one short, carrying a client_tracking_id |
| ② recover | GET /v1/forward-tests?tracking=<run id> — exact match, scoped to my account |
| ③ execution record | GET /v1/forward-tests/orders?format=csv&tracking=… — the whole account in one call |
| ④ join | Join to the tool's log on tracking id + client_order_id |
The intent stays with the tool. All that goes to the server is client_order_id, client_tracking_id and string metadata; the verdict (관망), the confidence (중간) and the MACD reasoning live only in tool_log.csv. If you need a number in metadata, carry it as a string — a float is rejected by canonical_json under its determinism rule and comes back 500.
Why long is long and short is short
Long — the tool said "buy if it comes down to 219.01, not now". So we do the opposite and buy at market now. The exit conditions are the tool's own numbers, unchanged:
{"symbol": "NVDA", "side": "long",
"exit_plan": {"stop_loss": "218.90", "take_profit": "230.00", "close_after_seconds": 600}}
Short — this tool explicitly implied downside: a MACD dead cross, inverted moving averages, a +3.82% gap above MA5, and "no chasing: do not buy above +5% over the 5-day line". There is no disclaimer saying this is not a prediction of a decline. So a short went out as well. Both levels are the tool's numbers with only their roles swapped:
{"symbol": "NVDA", "side": "short",
"exit_plan": {"take_profit": "219.01", "stop_loss": "234.50", "close_after_seconds": 600}}
219.01 is the tool's ideal_buy (= MA5), i.e. the pullback destination the tool named. 234.50 is the tool's resistance, identical across 3 of 3 chat runs. Not one new number was created.
One disclosure goes with the short: borrow fees on US equity shorts are computed as zero. Over ten minutes that barely registers, but hold one for long and the record flatters the market.
Environment for the numbers below: an isolated temporary server · synthetic quotes · not production · the P&L is not a market fact.
4. What came back
Both were 201, and neither filled.
| Case | Response | Entry | Exit | close_reason | Fees | Net P&L |
|---|---|---|---|---|---|---|
| NVDA long (buy now) | 201 |
— | — | rejected:market_closed |
0 | — |
| NVDA short (sell the pullback) | 201 |
— | — | rejected:market_closed |
0 | — |
"Was the hold right" is unmeasured this round.
Here is the measured session at run time.
venue=us-equity local_time=2026-09-28T00:27-04:00 is_open=False state=closed
next_open=2026-09-28T09:30-04:00 (= 22:30 KST)
Our screen — accepted with 201, then returned from placement as rejected:market_closed. Look at the fact that **acceptance (201) and placement (rejection) are separate stages**: direction and exit plan both passed validation, and the session is what stopped it
I did not fake the clock. A fill obtained around a closed session isn't a fill that passed the live rules. That's why step ⓪ of the recipe checks the session and stops on its own when it's closed. Run the same script between 22:30 and 05:00 KST and it lands on the same criterion.
Being unmeasured is free, and that was measured too
This rejection doesn't consume quota. In the same round, 16 submissions left used at 7, and 7 is exactly the number of crypto entries that actually filled — all 9 rejected:market_closed cases were refunded, because none of them ever filled.
And the account did not move. Comparing all nine account-related tables before and after gave complete equality (account_unchanged_vs_T0: true).
Our trial list — this run's cases gathered under one tracking id. Look at the **status column**: cases accepted without a fill and cases that ran to completion are distinguishable in the same list
What this round did answer
The main verdict is unmeasured. But the question from section 2 got an answer — moved into a counterfactual arrangement, the tool's levels pass acceptance validation as they are. Long gives stop 218.90 < entry < tp 230.00; short gives tp 219.01 < entry < sl 234.50. Neither came back 422.
The numbers I had written up as "not a viable order set" clear the contract purely because the entry moved. That is confirmed independently of the closed session, because acceptance validation runs before the session stage.
The Ask screen. Question history on the left; on the right, a MACD DIF 1.4828 < DEA 1.5377 table and a conditional trade plan. Look at **"the conditional trade plan I propose"** — the tool states its plan in prose. Executing that plan now, instead of waiting for its condition, is this article's counterfactual
5. What this combination can't tell you
① One sample says nothing. Here the sample is zero — the market was closed, so nothing filled. Even one verdict wouldn't settle whether the hold was right. You need a distribution.
② A counterfactual measures one side only. It measures "what if I had bought". "What did not buying save me" is still a judgment.
③ We don't say the tool was right or wrong. We measure and record. What this article says is not "the hold was correct" but "here is how you measure that hold, and this time the market was closed so I couldn't".
④ Unmeasured means unmeasured. Don't fill it with a zero. Not measuring and measuring zero are different things. These two cases must be excluded from any scoring table.
⑤ I chose the entry price. The tool never said "buy now". The entry timing of the counterfactual is mine, and that choice produces the result. Firing at the instant of the judgment is what removes the choice, and this was a late batch, so it didn't.
⑥ The tool's horizon and my window differ. Its levels assume a daily horizon; this window was ten minutes. A separate set matched to the tool's horizon is needed.
⑦ Borrow fees on US equity shorts are zero. Invisible over ten minutes, material over days, and always in the direction that flatters the record.
6. When to use this, and when not to
Use it when:
- your tool emits a verdict and price levels together and you've never checked whether the levels form a viable order set. Where you put the entry decides it
- the tool explicitly implies downside. Only then is a short counterfactual a translation rather than an invention
- the verdict repeats across runs. The steadier the verdict, the more it is worth measuring
Don't use it when:
- you're testing US equities during Korean daylight. It will be accepted and come back unmeasured. Let the recipe stop itself
- the tool didn't imply downside and you want to short anyway. "Don't buy" and "it will fall" are different claims. With a disclaimer present, the short is fiction
- you won't write down that you swapped roles. The short in this article used the tool's
ideal_buyas a target and its resistance as a stop. That assignment was mine, and it has to be stated - entry conditions are your tool's main output and this is your only path. A trial order has no entry-condition field, so that half disappears here
Evidence for this article: axis A counterfactual log · per-case request/response originals · transfer verdict · recipe. The original tool run is in part 25, daily_stock_analysis.