Moss raised its target ratio 3.0 → 3.3 after seeing our fees — I hung both targets on the same quote

Fed our real cost record, Moss raised `tp_rr_ratio` from 3.0 to 3.3. Hanging both targets on the same quote at the same instant showed that the 3.3 it chose can

Moss raised its target ratio 3.0 → 3.3 after seeing our fees — I hung both targets on the same quote

You've finished this article successfully if you can take one field a tool changed after feedback, hang the before and after values on the same millisecond, and read from the records what that single field changed.

What this does Translates the parameter a tool changed after seeing our cost record into price levels, hangs the before and after values on the same quote, and reads only that field's effect
Who it's for Anyone who has fed execution records back into a tool to revise its settings and never confirmed whether the revision helped
Who it isn't for Anyone whose tool emits only ratios and no per-trade levels. Without an anchor to translate from, this path doesn't stand up
What you end up with A comparison of how the before and after targets diverge on one identical fill, plus the recipe that produces it
Cost No code cost · no model cost · a weltiq pro account. N arms = N units of quota
Time / difficulty 20 minutes · medium (curl, JSON, plus a ratio-to-level conversion)
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 (section 5 states the limits plainly)
Disclosure The author is paid by weltiq for this series. The fact that the tool's revision killed its own evidence is written down as well

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 moss-trade-bot-skills in part 15. Give it one sentence of mission and an LLM fills in all 36 parameters, then runs its own backtest on that configuration and grades itself.

Moss filling in all 36 fields. One sentence of mission produces this much at once. Look at the fact that **every field is a ratio or a multiplier** — tp_rr_ratio, sl_atr_mult, risk_per_trade … not one absolute price. That is what bites in section 3

And its own backtest has no fees.

The two engines compared. Look at **zero occurrences of any fee string** — there is no line in Moss's backtest code that handles commission. If cost is zero inside its own world, a reason to revise settings because of cost can never arise there

So I fed it our cost record verbatim — pnl -98.02 fees 247.83, handed over as one line with no processing. Moss revised six of the 36 fields, and five of the six reasons mention fees.

Moss revising six fields after receiving the weltiq record. The blue line at the top is everything I handed over; below is the tool's answer. Look at the highlighted word **"수수료" (fees)** — an item that does not exist in its own backtest appears in five of the six reasons

One of them is the subject of this article.

Field Before After Moss's stated reason
tp_rr_ratio 3.0 3.3 "높은 수수료 부담을 감안해 이익 실현 시 비용을 흡수할 여지를 늘린다"

Of the six revised fields, this is the only one translatable into a price level. The rest are entry thresholds, moving-average periods, per-trade risk — things that don't descend to the levels of a single order.

That's the blank. Moss said it changed to 3.3, and nobody measured whether that was an improvement. Measuring it means running 3.0 and 3.3 under identical conditions, and those conditions never existed.


2. Why this stayed empty

Inside Moss's own world the question cannot even arise.

Its backtest has zero fees, so there's no reason to raise the ratio, and no way to see which trades die once it is raised. The evidence for the feedback comes from outside, and there is nowhere inside to check it.

Checking it outside means running 3.0 and 3.3 side by side, and the moment you execute, keeping everything else equal is hard.

Change one field and fire into the same instant and the same quote, and the difference can only come from that field.

A trial order doesn't use the balance and the server sets the quantity, so the two arms never compete for capital. Fire in the same millisecond and they see the same quote.


3. The recipe — the thing that actually runs

The recipe is here: 10-trial-order-moss-cost-feedback-ab.sh.

Step What
⓪ translate Derive price levels from the ratios and snap them to the tick grid. Write out the whole derivation
① plant Fire the two arms simultaneously. Same client_tracking_id; metadata.arm separates them
② recover GET /v1/forward-tests?tracking=<run id>
③ 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, and count whether published_at matches across arms

The intent stays with the tool. All that goes to the server is client_order_id, client_tracking_id and string metadata; neither the name tp_rr_ratio nor Moss's reason for raising it ever leaves tool_log.csv. A float in metadata is rejected by canonical_json under its determinism rule and comes back 500, so 3.3 went as a string too.

Ratio to level — the whole derivation

Moss's records carry ratios and no absolute levels. The anchor is the tool's own trade row (21-moss-own-backtest-30d.json trades[1]): SHORT · entry 76863.2 → exit 75943.85 · exit_reason: take_profit · pnl_pct 0.1196.

기록된 tp 거리 = 76863.2 − 75943.85 = 919.35        (rr 3.0 에서 실제로 난 거리)
→ sl 거리      = 919.35 / 3.0 = 306.45
→ SL           = 76863.2 + 306.45 = 77169.65 → 77169.6  (틱 0.1, 버림)
rr 3.3 의 tp 거리 = 306.45 × 3.3 = 1011.285
→ TP(비교군)   = 76863.2 − 1011.285 = 75851.915 → 75851.9 (틱 0.1, 버림)
TP(기준안)     = 75943.85 → 75943.8 (틱 0.1, 버림 — 숏 목표가는 내리는 쪽이 보수적)

sl_atr_mult stayed at 2.0 — an unchanged field — so the stop distance doesn't change either, and both arms got the same stop. Entry, direction and deadline are also identical. The only difference is the target.

The raw value doesn't go in as-is

75943.85 is not a multiple of the 0.1 tick on binance-usdm BTCUSDT. The transfer check confirmed it by sending the raw value.

422 invalid_take_profit  "75943.85 is not a multiple of tick 0.1"

Omit the deadline and you hit 422 exit_plan_deadline_required first — deadline validation runs before price validation.

The venue had to change

binance-spot has shortable=false and won't take a short, so this ran on binance-usdm (tick 0.1 · lot 0.001 · minimum notional 50 USDT). That is also a changed field, but since both arms use the same venue it is a constant inside the comparison.


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

The two arms went out at 13:28:50.398 and .406 — 8 milliseconds apart.

Arm tp_rr_ratio Target Accepted (KST) Entry fill Entry quote published Exit exit_trigger exit_trigger_px close_reason Fees Net P&L Elapsed
15-rr-30 (recorded) 3.0 75943.8 13:28:50.398 76855.363685 13:28:51.240 75951.444375 take_profit 75943.8 take_profit 0.07640340 +0.827515910 2.9s
15-rr-33 (Moss's revision) 3.3 75851.9 13:28:50.406 76855.363685 13:28:51.240 75951.444375 — — close_after 0.07640340 +0.827515910 46.0s

Both entry fills, and the publication time of the quote they referenced, match to the millisecond. One quote filled both.

Our trial detail with the one-field-apart arms lined up. Look at the **close_reason column** — one says take_profit, the other close_after. Same fill, same exit price, and yet **why they closed diverged**

Did that field decide the outcome — yes, and painfully

Where the market actually went was 75943.85. That value

The 3.3 that Moss raised after looking at fees cannot close, at target, the very trade that grounded that fee judgment.

That doesn't make the feedback wrong. Pushing the target further out to absorb cost is a sensible move. What it does mean is that the price of the move is invisible inside Moss's own world — a zero-fee backtest has no such thing as "a trade that died because the target moved". Hang both targets on the same quote at the same instant and you see it immediately.

The net P&L is identical for both arms, +0.827515910 to the last decimal, because the synthetic quote doesn't move after the exit and the deadline close landed at the same price. What diverged is not the P&L but the why and the when — and when you're validating feedback, that is exactly the information you need.

The export view, where each arm's record comes out as CSV. Look at the trailing columns — exit_trigger, exit_trigger_px and close_reason are what let you read "why didn't 3.3 close at target" from a spreadsheet

How many arms, and what it costs

Measured
6 arms fired at once into one quote 6/6 came back 201, zero failures or rejections, 0.02 seconds total, acceptance times spread over 6.5 milliseconds. No blocking code path
Quota N arms = N units. Part 15's two arms took used from 5 to 7
Resend / rejection / exit 0 units (same body resend 200 · different body 409 · automatic exits are counted: false)

On the pro tier's 1,000 a month, a two-arm comparison runs 500 times a month. Even a pair per feedback cycle leaves plenty over.


5. What this combination can't tell you

① One sample says nothing. The above is a single trade. It absolutely does not mean 3.3 is worse than 3.0 — it means that in this one trade 3.3 couldn't close at target. In another trade 3.3 might capture much more, which is the reason to raise the ratio in the first place. You need a distribution.

② A counterfactual measures one side only. It measures "how it closed with 3.3 set". "What 3.3 earned me extra" is still a judgment — the trades that ran further because the target was further out don't enter this window.

③ We don't say Moss's revision was right or wrong. We measure and record. The table says "that revision stopped this one trade closing at target", and nothing beyond it.

④ The P&L is not a market fact. It's arithmetic on synthetic quotes. What stands here is the ratio-comparison design.

⑤ The levels are derived. 75851.9 is not a number in Moss's records — I derived it from the tool's trade row. Change the derivation rule (section 3) and the number changes, and the conclusion might change with it. The only value the tool emitted is the ratio 3.3.

⑥ An unfilled arm never records the quote it saw. Both arms filled here, but a limit-price comparison in another round produced an unfilled one. reference_px is only the reference at acceptance, and published_at exists only after a fill. On top of that, an unfilled arm's close_after_seconds clock never even starts — it produces no result at all inside the observation window.

⑦ "Same quote" is circumstantial, not identification. Quote snapshots have no id. published_at matching to the millisecond is the best available evidence.

⑧ Recovering an experiment by tracking id opened right after this run. When this round ran there was no cross-lookup on ?tracking=, so recovery actually happened via the tag. The recipe uses the opened path, but the measurements above did not prove it.


6. When to use this, and when not to

Use it when:

Don't use it when:


Evidence for this article: axis B comparison log · per-case request/response originals · transfer verdict · recipe. The original tool run is in part 15, moss-trade-bot-skills.