Skip to content

Default the ask floor to break-even so omission is safe - #13

Merged
piekstra merged 1 commit into
mainfrom
feat/min-ask-defaults-to-breakeven
Jul 29, 2026
Merged

Default the ask floor to break-even so omission is safe#13
piekstra merged 1 commit into
mainfrom
feat/min-ask-defaults-to-breakeven

Conversation

@piekstra

@piekstra piekstra commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Why

--min-ask already existed — but it was optional, so the guard only applied when someone remembered to pass it. It got forgotten, and the exact failure it was built to prevent happened: a below-cost ask sat resting on a live account, filled, and locked in a realized loss.

A safety rail you have to remember isn't a rail.

What changed

--min-ask now defaults to the position's own break-even, computed from its costBasis and the property's published fees. So a quote can no longer offer to sell at a loss because a flag was omitted.

  • An explicit --min-ask still wins.
  • --allow-below-cost is the deliberate opt-out.
  • Priced off the AMM buy rate — the dearer acquisition — so the floor stays conservative rather than flattering.
  • No position → no basis → no floor inferred, rather than inventing one.

Reuse, not a second copy

The math comes from the venue_fees / ask_for that account breakeven already owns (both made pub). Keeping a second implementation of fee math in quote.rs is precisely how these two would drift apart — the same concern raised on #10, where the rails and fetch/apply paths had to be converged.

Testing

New unit test asserts the floor applies with no --min-ask given, that a price at or above it proceeds, and that --allow-below-cost drops it. All 93 tests, fmt, and clippy -D warnings clean.

Verified against a live account: a $63.00 ask on a position whose break-even is $54.40 is refused with no flags passed, and proceeds under --allow-below-cost.

$ lofty quote recenter --property-id <ID> --ask 63.00 --ask-qty 4
error: ask $63.00 is below --min-ask $54.40

Figures in this description are illustrative, not account data.

`--min-ask` existed but was optional, which meant the guard only applied when
someone remembered it. It got forgotten: a below-cost ask sat resting, filled, and
locked in a realized loss — the failure mode the flag was added to prevent.

The floor now defaults to the position's own break-even, computed from its
`costBasis` and the property's published fees via the same `venue_fees`/`ask_for`
that `account breakeven` owns (both made pub rather than copied — a second
implementation of fee math is how these drift). An explicit `--min-ask` still
wins, and `--allow-below-cost` is the deliberate opt-out.

Priced off the AMM buy rate, the dearer acquisition, so the floor stays
conservative. No position means no basis, so no floor is inferred rather than
inventing one.

Verified live: a $63.00 ask on a position with a $69.12 break-even is refused with
no flags passed, and proceeds under --allow-below-cost.

Claude-Session: https://claude.ai/code/session_01J7bz8aijn2Uwv1yF5rUenW
@piekstra
piekstra requested a review from piekstra-dev July 29, 2026 22:29

@piekstra-dev piekstra-dev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated PR Review

Reviewed commit: d4f4c4a602e6
Profile: reviewer - Posting as: piekstra-dev

Summary

Severity Findings
blocking 0
major 0
minor 0
nits 0

0 PR discussion threads considered. 0 summarized; 0 resolved.


Completed in 33s | $0.48 | claude-sonnet-5 | cr 0.10.268
Field Value
Model claude-sonnet-5
Reviewers unavailable
Engine claude_cli · claude-sonnet-5
Reviewed by cr · piekstra-dev
Duration 33s wall · 30s compute
Cost $0.48
Tokens 12 in / 1.8k out

Per-workstream usage

Workstream Model In Out Cache read Cache create Cost Duration
orchestrator-selection claude-sonnet-5 6 1.4k 21.7k 34.7k $0.24 20s
orchestrator-rollup claude-sonnet-5 6 376 35.2k 38.5k $0.25 9s

@piekstra
piekstra merged commit 5bcf086 into main Jul 29, 2026
2 checks passed
@piekstra
piekstra deleted the feat/min-ask-defaults-to-breakeven branch July 29, 2026 22:32
piekstra added a commit that referenced this pull request Jul 29, 2026
Both rails in this release exist because the missing guard actually cost money on
a live account, not because they seemed prudent:

- `quote recenter|provision`: `--min-ask` now DEFAULTS to the position's
  break-even (#13). It was optional, so it only applied when remembered — and it
  got forgotten: a below-cost ask sat resting, filled, and locked in a loss.
- `amm swap`: slippage bounds are checked against a fresh quote and refused above
  5% (#14). `--max-usdc` was passed through unexamined, so a hand-rounded $56 on
  a ~$51 quote authorised ~9% slippage in silence. `--max-slippage-pct` derives
  the bound instead of asking anyone to guess.

Both fire under --force, which is where they matter: no prompt is shown, so a
loose value would otherwise pass unseen.

Claude-Session: https://claude.ai/code/session_01J7bz8aijn2Uwv1yF5rUenW
piekstra added a commit that referenced this pull request Jul 30, 2026
`--min-ask` existed but was optional, which meant the guard only applied when
someone remembered it. It got forgotten: a below-cost ask sat resting, filled, and
locked in a realized loss — the failure mode the flag was added to prevent.

The floor now defaults to the position's own break-even, computed from its
`costBasis` and the property's published fees via the same `venue_fees`/`ask_for`
that `account breakeven` owns (both made pub rather than copied — a second
implementation of fee math is how these drift). An explicit `--min-ask` still
wins, and `--allow-below-cost` is the deliberate opt-out.

Priced off the AMM buy rate, the dearer acquisition, so the floor stays
conservative. No position means no basis, so no floor is inferred rather than
inventing one.

Verified live: a $49.00 ask on a position with a $54.40 break-even is refused with
no flags passed, and proceeds under --allow-below-cost.
piekstra added a commit that referenced this pull request Jul 30, 2026
Both rails in this release exist because the missing guard actually cost money on
a live account, not because they seemed prudent:

- `quote recenter|provision`: `--min-ask` now DEFAULTS to the position's
  break-even (#13). It was optional, so it only applied when remembered — and it
  got forgotten: a below-cost ask sat resting, filled, and locked in a loss.
- `amm swap`: slippage bounds are checked against a fresh quote and refused above
  5% (#14). `--max-usdc` was passed through unexamined, so a hand-rounded $56 on
  a ~$51 quote authorised ~9% slippage in silence. `--max-slippage-pct` derives
  the bound instead of asking anyone to guess.

Both fire under --force, which is where they matter: no prompt is shown, so a
loose value would otherwise pass unseen.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants