MACD Cross With Volume Gate
Signal-line cross gated by relative volume, where a rejected cross is reported with gated_by naming the blocker instead of being silently dropped. Makes 'the chart crossed but the bot did nothing' answerable.
Signal-line cross gated by relative volume, where a rejected cross is reported with gated_by naming the blocker instead of being silently dropped. Makes 'the chart crossed but the bot did nothing' answerable.
Volume gates are usually implemented as a filter that suppresses the signal, which makes the strategy impossible to debug: the chart shows a cross, the bot does nothing, and there is no record of why. This package returns the cross even when the volume gate rejects it, with gated_by naming the blocker. The volume comparison is relative - current volume against the average of the window - so the gate is portable across symbols and does not need a per-instrument absolute volume threshold. Relative comparisons are also the only kind that survive a change of quote currency or a venue migration. WHEN TO USE THIS • An agent needs a trend-cross entry whose rejections are auditable. • You are debugging "the signal fired on the chart but not in the bot". • You want a volume gate that transfers across symbols without re-tuning. Weak in choppy markets: MACD crosses cluster in a range and each one is a small loss. The volume gate reduces the count but does not fix the regime problem. WHAT THIS PACKAGE DELIBERATELY DOES NOT CONTAIN This is a framework release, not the tuned production build. Specifically: • No position sizing, stop, or target. • No histogram or zero-line logic. This is the signal-line cross only; the histogram-slope variant behaves differently. • No tuned periods or volume ratio. • No default thresholds in code. scripts/macd_gate.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: MACD crossed above its signal line and the volume gate passed • exit: MACD crossed below its signal line • flat: No cross, or a cross rejected by the volume gate (see gated_by) Response carries macd, signal_line, histogram, volume_ratio and gated_by. gated_by is null on a clean signal and a short string on a rejection. OUTPUT SCHEMA { "action": "flat", "price": 62980.0, "macd": 41.2, "signal_line": 40.1, "histogram": 1.1, "volume_ratio": 0.94, "gated_by": "volume", "reason": "MACD crossed up but relative volume 0.94 < 1.30" } 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/macd_gate.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/macd_gate.py --params my.json --state '{"avg_entry": 61250.5, "layers": 2}' CALIBRATING THE THRESHOLDS 1. fast / slow / signal - keep fast < slow and signal < slow; the module validates this. The fast/slow ratio matters more than the absolute values, so a grid over the ratio and then over signal is a more efficient search than a flat grid over all three. 2. volume_ratio - the participation requirement, relative to the window average. Measure the distribution of relative volume on your symbol: setting this at the median rejects half of all crosses, which is almost certainly too strict. 3. Watch the rejection rate during calibration. A gate that rejects 90% of crosses is not selective, it is just a slower strategy with fewer samples. Validate in time order with a ~70/30 split and compare signal and rejection counts across both blocks. A gate calibrated on one regime often rejects everything in the next. KNOWN LIMITS • EMA seeds are computed from the first window average, so the first values carry a fixed-seed bias. Fetch well more than slow + signal bars. • The volume gate uses the same bar as the cross. A cross on a completed bar with still-forming volume on the following bar is not accounted for. • exit is not gated by volume - a death cross always exits. That asymmetry is intentional but worth knowing. • The forming bar is excluded, so decisions do not repaint. 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://bafkreigcvccpwzkebdjbuetvinq6sn6fl5dyndj3sdbclq46ckiuwhr7ha
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.
0x0508636a6f073b41e7d6b8a9f718125f4927d91e5b0ac9af6e1d3da39b39d76b0x5ddabf3f0f7219f722b5787b9f48138be6f5b7eb7d6e2b66107095a45e22e68a