Volume-Confirmed Range Breakout
A breakout only counts when the preceding window was genuinely tight and the breakout bar carried volume. Both conditions are relative, and failed_on names which one rejected the bar.
A breakout only counts when the preceding window was genuinely tight and the breakout bar carried volume. Both conditions are relative, and failed_on names which one rejected the bar.
"Price broke the range high" is an incomplete sentence. It says nothing about whether there was a range - a wide bar in a choppy market breaks the prior high every few bars - and nothing about whether anyone participated. This package requires both. The window before the breakout must be tight relative to its own midpoint, and the breakout bar's volume must exceed the same window's average by your multiple. Both tests are dimensionless, so one calibrated pair works across symbols. The output reports tightness and volume_ratio on every call, including failures, so a strategy that never fires can be diagnosed rather than guessed at. WHEN TO USE THIS • An agent must decide whether a range breakout is backed by participation. • You are debugging a breakout strategy that fires constantly in chop. • You want a dimensionless tightness measure you can compare across symbols. Loses most of its edge on news-driven gaps, where the range and volume conditions are both satisfied but the move is already complete. WHAT THIS PACKAGE DELIBERATELY DOES NOT CONTAIN This is a framework release, not the tuned production build. Specifically: • No position sizing, stop, or target. Breakout entries need all three. • No multi-window scan. One window, one decision. • No tuned bar count, volume multiple, or break percentage. • No default thresholds in code. scripts/range_breakout.py raises PARAM_INCOMPLETE rather than falling back to a number. A silent default would make you believe you are running a calibrated system when you are running someone else's parameters. Every decision boundary is an input. That is the whole contract. DECISION CONTRACT • action: Condition • long: The n bars before the last one are tight and the last close exceeds their high by breakout_pct and volume clears the multiple • flat: Any condition fails; failed_on names which Response carries range_high, range_low, tightness, volume_ratio and failed_on. failed_on is null on a signal. OUTPUT SCHEMA { "action": "flat", "price": 63110.0, "range_high": 62980.0, "range_low": 62400.0, "tightness": 0.00921, "volume_ratio": 1.31, "failed_on": "volume", "reason": "broke the range but relative volume 1.31 < 1.60" } action is the only field you must branch on. reason is meant for logs and for an agent to quote back to a human — do not parse it. RUN IT python3 scripts/range_breakout.py \ --params references/params-example.json \ --symbol BTC/USDT \ --interval 1h references/params-example.json holds round, obviously-illustrative numbers. They exist so the command runs on the first try, not because they are good. Feeding position state in: python3 scripts/range_breakout.py --params my.json --state '{"avg_entry": 61250.5, "layers": 2}' CALIBRATING THE THRESHOLDS 1. consolidation_bars - the length of the base. Longer windows find rarer, more meaningful ranges; shorter windows turn the rule into a momentum filter. At a 1h interval, 24 bars is roughly a day, which is a reasonable starting hypothesis to test rather than a recommendation. 2. volume_ratio - measure the empirical distribution of relative volume first. The median is 1.0 by construction, so a multiple near 1.0 gates almost nothing. 3. breakout_pct - the decisiveness beyond the range high. Anchor it to the bar range, not to a round number; a break that is smaller than typical bar noise is not a break. All three interact: a tighter range needs a smaller break percentage to be meaningful. Grid them together, then hold out the most recent ~30% in time and check the signal count in each block before judging returns. KNOWN LIMITS • Tightness is measured on the pre-break window only, so a range that widens into the breakout is still judged by its quiet phase. • Volume is taken from the same bar as the breakout. Feeds that report partial volume for the forming bar will understate it - this module drops the forming bar, but the bar before it may still be incomplete on some APIs. • The rule is long-only. A symmetrical breakdown is not implemented. • No gap handling: a large open above the range satisfies both conditions at once. DISCLAIMER This is a decision framework for research and education. It is not investment advice, not a profit claim, and not a backtest result. Crypto derivatives can lose more than the deposit. You are responsible for the parameters you choose and for every order your executor places.
ipfs://bafkreicgfcbuuqpfmtuoqgdxri66clnxkak6syifsqatvrlvscc5k5yjqi
The primary-document hash is the SHA-256 of the plaintext primary Markdown file. The content-commitment hash covers the verified SkillRoot structure, or plaintext ZIP for older Skills; it is not the hash of the downloaded file.
Opaque identifiers and fingerprints are hidden from the primary experience but remain available for exact verification.
0x779fef8bb852ed9a28ed1d08690da50fe3ba5cfd1abee128447361086acf3bce0x9c79efdbfb2df4c54b7fc52d9d4a92ba23153dc7d34a1da056abad11262518ad