feat(strategy_ladder_buys): cap consecutive rungs per drawdown#7
Open
peeyush20 wants to merge 1 commit into
Open
feat(strategy_ladder_buys): cap consecutive rungs per drawdown#7peeyush20 wants to merge 1 commit into
peeyush20 wants to merge 1 commit into
Conversation
Closes a gap surfaced in the README review: ladder_buys has nothing
stopping it from buying every drop in a sustained downtrend until cash
runs out. Adds a per-stock cap on both rung count and cumulative
notional invested, both reset on any sell.
New tunables (persistence/config/strategy_defaults.json)
- ladder_buys.max_rungs = 4 — entry counts as rung 1, so this
means entry + 3 dip adds before
the strategy pauses on this stock.
- ladder_buys.max_position_usd = 2000 — additive belt-and-suspenders. Even
if max_rungs were misconfigured,
cumulative invested-since-last-sell
on one stock is bounded.
State (lib/pool.sh)
- New per-stock fields strategy_config.ladder_buys.consecutive_buys and
consecutive_invested_usd. Initialised to 0 in pool_add_stock.
- New helper pool_increment_ladder_consecutive bumps both atomically.
Uses // 0 fallbacks so it's safe against the pre-counter empty {}
layout in existing pool.json files.
- pool_set_last_sell now resets both counters. Triggers on any sell —
partial (profit_take) or full (trailing_stop) — so each new
accumulation cycle starts with a fresh budget.
Strategy enforcement (.claude/skills/strategy_ladder_buys/scripts/apply.sh)
- Two new short-circuit checks before notional sizing:
rung_cap_hit — emits status:"skipped" reason "max_rungs reached (N/M)"
pos_cap_hit — emits "max_position_usd reached (\$X/\$Y)"
- The notional sizing min() is extended with remaining_pos = max_pos -
consecutive_invested, so the final rung uses a partial notional rather
than overshooting the cap.
- Successful orders' reason now includes "(rung N/M)" — operator can see
cap pressure at a glance in the snapshot.
Doc (.claude/skills/strategy_ladder_buys/SKILL.md)
- New "Consecutive-rung cap" section explaining both knobs, reset-on-sell
semantics, the per-stock override path, and the manual-close caveat
(closing a position in the Alpaca web UI does NOT reset the counter —
same divergence problem as elsewhere; pointed at so operators hitting
it know what to do).
- First-rung handling note updated to flag that cold-start counts as
rung 1.
Backward compat
- Existing pool.json entries with ladder_buys: {} still work. The
// 0 fallbacks treat missing fields as zero on read; the next
pool_increment populates them.
- pool_strategy_config already merges defaults into per-stock overrides,
so the new max_rungs / max_position_usd defaults automatically apply
to stocks added before this change.
Verified
- bash -n on pool.sh and apply.sh; jq parse on strategy_defaults.json.
- 7-step functional test of pool_add_stock / pool_increment_ladder_consecutive
/ pool_set_last_sell / pool_strategy_config in a sandbox repo, including
a backward-compat path and cap-hit arithmetic. All pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes a gap surfaced in the README review: ladder_buys has nothing stopping it from buying every drop in a sustained downtrend until cash runs out. Adds a per-stock cap on both rung count and cumulative notional invested, both reset on any sell.
New tunables (persistence/config/strategy_defaults.json)
means entry + 3 dip adds before
the strategy pauses on this stock.
if max_rungs were misconfigured,
cumulative invested-since-last-sell
on one stock is bounded.
State (lib/pool.sh)
Strategy enforcement (.claude/skills/strategy_ladder_buys/scripts/apply.sh)
pos_cap_hit — emits "max_position_usd reached ($X/$Y)"
consecutive_invested, so the final rung uses a partial notional rather
than overshooting the cap.
cap pressure at a glance in the snapshot.
Doc (.claude/skills/strategy_ladder_buys/SKILL.md)
Backward compat
Verified