Strategy file: quantroduction-mixer-futures.js Market: futures
Description
Quantroduction Mixer (Futures). Long & short via closeMarket/closeLimit. Tracks gb.data.currentSide as source of truth. Same 11-indicator confluence as spot. Signal reversal closes current side first then re-enters opposite next cycle.
How it works
Futures variant of the Mixer (see Spot variant for the full theoretical grounding). The futures version adds leverage-aware weighting: each underlying signal's notional contribution is normalised by the leverage at which it will be expressed, so a 3x leveraged momentum sleeve and a 1x mean-reversion sleeve combine into a coherent target exposure. Funding rate is included as a carry component when the underlying perpetual has structural basis. Same combination math (Markowitz / risk-parity) applies but the realised volatility used for weighting is computed on leveraged returns, not raw underlying.
Allocation
How much of THIS pair’s wallet the strategy may use, what it must start with, and the hard config gate. Trading is BLOCKED until Wallet allocation % is set AND Allocation confirmed is ON. Optional grid splits an order into laddered post-only rungs for better fills.
| Key | Type | Default | Description |
|---|---|---|---|
ALLOC_PCT |
range (range 1..100) | 25 |
Percentage of THIS pair’s wallet balance the strategy may deploy. Effective cap = min(wallet × this %, the absolute Capital allocation). Every order is clamped to it and can never exceed it. REQUIRED — trading is blocked until this is set (>0) and Allocation confirmed is ON. |
ALLOC_CONFIRMED |
boolean | False |
Explicit acknowledgement that the allocation above is correct for this pair. The strategy will NOT place any entry order until this is ON. A clear "ALLOCATION CONFIGURED" line is logged once it is; otherwise an "ALLOCATION NOT CONFIGURED — refusing to trade" line is logged each cycle. |
ALLOC_SPLIT_TOL |
range (range 0..100) | 15 |
How far the starting base/quote split may deviate from what this strategy needs before it refuses to start. Long-only strategies want mostly quote/cash; two-sided market-makers want ~50/50 base/quote; futures want free margin. Mismatch beyond this % blocks trading (unless Enforce start inventory is OFF). |
ALLOC_ENFORCE_SPLIT |
boolean | True |
When ON, the strategy refuses to trade until the starting base/quote split is within tolerance of what it needs (archetype-aware). When OFF, a mismatch is logged as a warning but trading proceeds. |
ALLOC_AUTO_REBALANCE |
boolean | True |
Two-sided market-makers only. ON by default: if the pair starts off the target base/quote split, the strategy places a single bounded market order on start to reach it (e.g. buys ~half the allocation into base for a 50/50 maker), then begins normal trading. Set to OFF to instead stay blocked and log the exact amount to buy/sell manually. Long-only and futures strategies ignore this. |
ALLOC_RESERVE_PCT |
range (range 0..50) | 0 |
A buffer, as % of wallet, kept BELOW the allocation cap and never deployed. Use to leave headroom for fees/slippage. Effective cap = min(wallet × allocation %, absolute cap) − wallet × this %. |
MXF_GRID |
boolean | False |
When ON, an entry order is split into several laddered post-only rungs across a price band instead of one order — often gets better average fills. Cumulative size is still clamped to the allocation. OFF = single order. |
MXF_GRID_LEVELS |
range (range 2..10) | 3 |
Number of laddered rungs to split an entry into when "Split entries into a grid" is ON. More rungs = finer fills but more orders. |
MXF_GRID_SPAN_PCT |
range (range 0.1..5) | 0.5 |
Price band width, as % from the reference price, across which the grid rungs are spread. e.g. 0.5 places rungs from the reference price down to 0.5% below it (for buys). |
Confluence
How the 11 indicator filters combine into a single signal
| Key | Type | Default | Description |
|---|---|---|---|
MXF_ALLOW_LONG |
boolean | True |
Master toggle for long-side trading |
MXF_ALLOW_SHORT |
boolean | True |
Master toggle for short-side trading |
MXF_REQUIRE_ALL |
boolean | False |
TRUE = all enabled indicators must agree (AND, strict). FALSE = any single one fires the signal (OR, loose). |
MXF_COOLDOWN_MS |
range (range 0..120000) | 12000 |
Minimum delay between order actions. Prevents duplicate orders on fast cycles. |
Indicator Toggles
Turn each indicator on or off independently
| Key | Type | Default | Description |
|---|---|---|---|
MXF_USE_SMA_CROSS |
boolean | True |
Fast SMA above slow = bullish; below = bearish |
MXF_USE_RSI |
boolean | False |
RSI > LONG_ABOVE = bullish; < SHORT_BELOW = bearish |
MXF_USE_MACD |
boolean | False |
MACD above signal = bullish; below = bearish |
MXF_USE_SUPERTREND |
boolean | False |
Supertrend below price = bullish |
MXF_USE_STOCHASTIC |
boolean | False |
%K > 50 bullish; < 50 bearish |
MXF_USE_BB |
boolean | False |
Price above BB middle = bullish |
MXF_USE_EMA_CROSS |
boolean | False |
Fast EMA above slow = bullish |
MXF_USE_AO |
boolean | False |
AO > 0 bullish; < 0 bearish |
MXF_USE_SAR |
boolean | False |
SAR below price = bullish |
MXF_USE_CCI |
boolean | False |
CCI > LONG_ABOVE bullish; < SHORT_BELOW bearish |
MXF_USE_ADX |
boolean | False |
ADX > threshold confirms trend; DI+ vs DI- gives direction |
Indicator Parameters
Periods and thresholds for each indicator
| Key | Type | Default | Description |
|---|---|---|---|
MXF_SMA_FAST |
range (range 2..50) | 5 |
|
MXF_SMA_SLOW |
range (range 5..200) | 10 |
|
MXF_RSI_LEN |
range (range 2..100) | 14 |
|
MXF_RSI_LONG_ABOVE |
range (range 0..100) | 50 |
RSI must exceed this to register bullish |
MXF_RSI_SHORT_BELOW |
range (range 0..100) | 50 |
RSI must drop below this to register bearish |
MXF_MACD_FAST |
range (range 2..50) | 12 |
|
MXF_MACD_SLOW |
range (range 5..100) | 26 |
|
MXF_MACD_SIGNAL_LEN |
range (range 2..50) | 9 |
|
MXF_ST_ATR_LEN |
range (range 2..50) | 10 |
|
MXF_ST_FACTOR |
range (range 1..10) | 3 |
|
MXF_STOCH_K |
range (range 2..50) | 14 |
|
MXF_STOCH_D |
range (range 1..20) | 3 |
|
MXF_STOCH_SMOOTH |
range (range 1..20) | 3 |
|
MXF_BB_LEN |
range (range 5..100) | 20 |
|
MXF_BB_MULT |
range (range 1..5) | 2 |
|
MXF_EMA_FAST |
range (range 2..50) | 5 |
|
MXF_EMA_SLOW |
range (range 5..200) | 10 |
|
MXF_AO_FAST |
range (range 2..50) | 5 |
|
MXF_AO_SLOW |
range (range 5..200) | 34 |
|
MXF_CCI_LEN |
range (range 2..100) | 20 |
|
MXF_CCI_LONG_ABOVE |
range (range -200..200) | 0 |
|
MXF_CCI_SHORT_BELOW |
range (range -200..200) | 0 |
|
MXF_ADX_LEN |
range (range 2..50) | 14 |
|
MXF_DI_LEN |
range (range 2..50) | 14 |
|
MXF_ADX_THRESHOLD |
range (range 10..50) | 20 |
ADX must exceed this for trend confirmation |
Exits
Stop loss, break-even guard, take profit
| Key | Type | Default | Description |
|---|---|---|---|
MXF_STOP_LOSS_ENABLED |
boolean | True |
|
MXF_STOP_LOSS_PCT |
range (range 0.1..10) | 2 |
Percentage below entry price |
MXF_BREAK_EVEN_GUARD |
boolean | True |
Refuse any exit at a net price below break-even (includes fees) |
MXF_BE_OVERRIDE_CYCLES |
range (range 0..100) | 10 |
After this many blocked cycles, SL fires anyway. Set 0 to disable override. |
MXF_ESTIMATED_FEE_PCT |
range (range 0..1) | 0.08 |
Used for futures BE calc when gb.data.breakEven is unavailable. Typical taker 0.08%. |
Sizing & Runtime
Order size, minimum sell amount, base trading limit
| Key | Type | Default | Description |
|---|---|---|---|
PERIOD |
select | 1 |
Gunbot core PERIOD |
MXF_TAKE_PROFIT_LEVELS |
string | [{"pct":0.4,"portion":0.34},{"pct":0.8,"portion":0.33},{"pct":1.5,"portion":1.0}] |
Multi-level TP table as a JSON array of {pct, portion} objects. pct = % from entry to trigger (above for longs, below for shorts); portion = fraction of CURRENT position to close at that level (0.0-1.0). Set the final level's portion to 1.0 to guarantee full close. Default: 34% at +/-0.4%, 33% at +/-0.8%, rest at +/-1.5%. Must be valid JSON; invalid input falls back to the in-code default. |
TRADING_LIMIT |
range (range 10..10000) | 100 |
Gunbot-level order size cap in quote currency |
BE_GUARD |
boolean | True |
Wraps Gunbot sell methods. Blocks sells priced below data.breakEven while holding a long. Buys never affected. |
MXF_TRADING_LIMIT_BASE |
range (range 10..10000) | 100 |
Fallback base-currency amount if strategy config lacks TRADING_LIMIT |
MXF_MIN_CLOSE_QTY |
range (range 0..10) | 0.001 |
Avoid dust closes on futures contracts |
VERBOSE_LOGS |
boolean | False |
When ON, the full Quantroduction × Gunbot dashboard (every config value + state snapshot) re-emits every VERBOSE_INTERVAL_MIN minutes for forensic audit. When OFF (default), the dashboard only fires once per Gunbot restart per pair. |
VERBOSE_INTERVAL_MIN |
range (range 5..240) | 30 |
How often the dashboard re-emits when VERBOSE_LOGS is ON. Lower = more frequent / noisier; higher = quieter. Has no effect when VERBOSE_LOGS is OFF. |
BE_GUARD_BLOCK_MARKET_SELLS |
boolean | True |
Default ON (legacy). Set OFF to enable SOFT BE_GUARD: market sells and closeMarket pass through (treated as urgent / stop-loss). Only limit sells below break-even remain blocked. Prevents BE_GUARD from silently swallowing stop-loss exits. |
SCRATCH_LIVENESS_MIN |
range (range 0..120) | 0 |
When >0: if the pair holds inventory and hasn't filled in N minutes AND the bid is at break-even+1bp, force a market exit to rotate capital. 0 = disabled. Typical: 30. |
CONSEC_RESET_CYCLES |
range (range 60..2880) | 480 |
After this many cycles without any order activity, auto-reset consecutiveLosses to 0. Default 480 cycles ≈ 2h at 15s/cycle. Prevents a 3-loss streak from killing the pair for the entire session. |
DRIFT_ATR_FRAC |
range (range 0..0.5) | 0 |
When >0: scale drift-requote threshold to this fraction of the recent 10-candle high-low range (clamped 2-100 bps). 0 = use fixed *_STALE_DRIFT_BPS. Typical: 0.05 = 5% of recent range. Adapts drift detection to per-pair volatility. |
SKEW_QTY_MAX |
range (range 1..5) | 2.5 |
Maximum ask:bid qty ratio when inventory is heavily skewed. 2.5 means a heavily-bagged pair quotes up to 2.5x ask qty vs bid qty to drain inventory faster. Set 1.0 to disable (symmetric quoting). |
SKEW_QTY_TARGET |
range (range 0.1..0.9) | 0.5 |
Target inventory fraction of pair equity. 0.5 = 50/50 balanced base/quote. Skew kicks in proportionally as actual exposure deviates from target. |
PORTFOLIO_INCLUDE |
boolean | True |
When ON (default), this pair participates in the shared PORTFOLIO_EXP_BUDGET — its exposure counts toward portfolio total and bids pause when budget is exceeded. When OFF, the pair stands alone (use PAIR_EXP_BUDGET for own cap). |
PORTFOLIO_EXP_BUDGET |
range (range 0..1) | 0 |
Cap on total portfolio inventory as fraction of total allocated equity (sum across PORTFOLIO_INCLUDE pairs). 0 = disabled. Typical: 0.6 = 60% inventory cap across the included portfolio. When exceeded, bids pause but exits remain active. |
PAIR_EXP_BUDGET |
range (range 0..1) | 0 |
This pair's own exposure cap as fraction of pair equity (inventory / pair allocated capital). Applies independently of portfolio budget. 0 = disabled. Typical: 0.2 = 20% per-pair cap. |
DISABLE_BREAKER_WINDDOWN |
boolean | False |
When OFF (default), an active breaker (3 consecutive losses or daily loss limit) actively frees capital: cancels open orders and scratch-sells inventory IF profitable (bid >= BE+1bp). When ON, legacy halt-and-hold behaviour. |
TRACE_ALL |
boolean | False |
Master switch for the Quantroduction tracer. When ON, writes detailed per-cycle JSONL to gunbot_logs/quantroduction/ AND emits a verbose console summary. Equivalent to setting every |
Portfolio & Runtime (per-pair overrides)
Per-pair runtime knobs. Override any of these on a single pair without changing the strategy defaults.
| Key | Type | Default | Description |
|---|---|---|---|
NO_CLOSE_MARKET |
boolean | False |
On exchanges that don't expose closeMarket reliably, set this to true to force the compat wrapper to route every close through sellMarket / buyMarket instead. |
NO_POST_ONLY |
boolean | False |
On exchanges that reject post-only orders (e.g. some DEX flavours), force the compat wrapper to fall back to plain limit orders. Increases taker risk; only enable if your exchange genuinely cannot process post-only. |
RESET_BREAKER_ONCE |
boolean | False |
Set to true once to clear any tripped circuit breaker (consecutive-loss / daily-loss). The strategy auto-clears this flag after the reset fires so you don't have to remove it. |
RESET_STATS_ONCE |
boolean | False |
Set to true once to zero out wins, losses, consecutive losses, peak equity, max drawdown, trade count, and daily-loss lock. Total PnL is preserved. The flag auto-clears after the reset fires. |
LOG_LEVEL |
select | NORMAL |
Controls how verbose the strategy's logs are. QUIET only logs errors and trade events. NORMAL adds breaker / state changes. VERBOSE adds per-cycle gate decisions (useful for tuning). |
MIN_ORDER_QUOTE |
range (range 1..50) | 5 |
Minimum notional that the exchange will accept for an order, in quote currency. Set higher than the exchange's true minimum to leave buffer for slippage on validation. |
QUANTRODUCTION_TRACE |
boolean | False |
Master switch for the diagnostic tracer. When on, every gate decision and breaker event is recorded so you can see exactly why the strategy did or did not act this cycle. |
WARMUP_CYCLES |
range (range 0..50) | 5 |
How many cycles the strategy waits at startup before placing any orders. Lets indicators warm up and the strategy compute a baseline before reacting. |
SPREAD_PNL_JUMP_GUARD |
range (range 0.1..1) | 0.5 |
Realized-PnL deltas larger than this fraction of pair equity are treated as deposits/withdrawals/data-glitches and skipped. Default 0.5 means a single delta over 50% of equity is ignored. Lower for tighter glitch detection on small accounts. |
References & further reading
- Markowitz, H. (1952). Portfolio selection. Journal of Finance 7(1), 77–91.
- Maillard, S., Roncalli, T. & Teïletche, J. (2010). The properties of equally weighted risk contribution portfolios. Journal of Portfolio Management 36(4), 60–70.
- Moskowitz, T. J., Ooi, Y. H. & Pedersen, L. H. (2012). Time series momentum. Journal of Financial Economics 104(2), 228–250.
Configuration playbook
- Full Tier 1-3 stack: see
OPERATOR_GUIDE.mdquick-start - Standalone pair (not in portfolio):
"PORTFOLIO_INCLUDE": false, "PAIR_EXP_BUDGET": 0.20 - Clear stuck breaker:
"RESET_BREAKER_ONCE": true - Clear historical loss counters:
"RESET_STATS_ONCE": true(preserves total PnL) - Enable JSONL tracer:
"TRACE_ALL": true - Soft BE_GUARD:
"BE_GUARD": true, "BE_GUARD_BLOCK_MARKET_SELLS": false