Most screeners are good at showing what just moved; very few help you systematically trade what matters next.
Gunbot Quant is a standalone, open-source workflow that links saved screener setups directly to batched backtests. If you use Gunbot DeFi, you can hand those tested configs to your live bot in one click.
The integration offers a repeatable loop from “scan like an algo trader” → “prove it” → “run it,” in one place you control.
This is not a claim to be the only capable screener. Plenty of screeners exist, and if you just want to eyeball opportunities, you’ll be served. The difference here is architecture and intent: saved, composable scans that speak the same language as the backtester; caching and compiled computations so re-runs are fast; and reporting that answers the questions systematic traders ask before putting capital at risk.
The screener is good; the workflow from saved scan → batch test → live parity → monitoring is the point.
Free and open source. Use it, fork it, improve it. Pull requests welcome.
Repository: https://github.com/GuntharDeNiro/gunbot-quant
What is it
Gunbot Quant is a research and deployment workflow for algorithmic trading that runs locally, talks to multiple data sources, and treats trading as a reproducible experiment rather than a weekend of tab-surfing.
You define a scan once with liquidity guardrails plus momentum, volatility, and trend metrics, then save it with a clear name. Reuse it whenever that strategy archetype applies. When you hit “go,” the screener assembles a candidate set that fits your rules, and the backtester runs that strategy (or a portfolio of strategies) across all candidates in one sweep. Reports include risk-adjusted results, portfolio roll-ups, and exit-reason diagnostics so you can separate a pretty equity curve from a setup that actually earned its keep.
If you run Gunbot, you can send the exact tested configuration to live trading in a click. If you don’t, you can still use the scans, tests, and reports as an independent research layer.
Net effect: parameters used live match the ones tested; live pairs can be benchmarked against the rest of the market; and screeners don’t get rebuilt from scratch when regimes change — pull up the saved scan for that regime, batch test again, and compare.
Key idea: saved screener setups flow straight into batched backtests with the same parameters and symbol normalization. Define once, reuse often, compare over time.
Screener: a research starting point you can save and reuse
A screener for algos is less about colorful dashboards and more about not wasting backtest compute.
Gunbot Quant pulls from any CCXT-compatible crypto exchange and from Yahoo Finance for equities and ETFs. It normalizes symbols so “the thing you tested” is “the thing you can trade.” Think of the process as a funnel: start with a wide net of higher-volume assets, then apply increasingly specific filters.
Practical filters:
– Liquidity using trading volume, to avoid thin books.
– Price versus SMAs, to avoid testing trend followers in chop or mean-reverters in one-way markets.
– Momentum via rate-of-change windows aligned with your timeframe.
– Normalized volatility via ATR percentage, so grids don’t get dead pairs and breakout systems don’t get handed whipsaw machines.
– Oscillators like RSI and Stoch RSI when the logic needs them.
– Heuristics such as volatility consistency, recent volume concentration, and spike filters to keep unsuitable candidates out.
Saving is the point. Keep named, versioned scans like “TrendCandidates-Daily-HighADX” or “LowVol-MeanRev-4h.” When market tone shifts, run the same scan and get a fresh ranked list that passes the same gates.
Symbols and exchanges note: market naming gets messy across platforms. The app normalizes symbols so your research symbol matches the live tradable pair on your exchange.
Available screener metrics:
– Volume: avg_vol_30d_quote (sustained liquidity), rel_vol_10d_quote (recent attention spikes).
– Momentum: roc_*p (movement strength across horizons).
– Trend: price_vs_sma* (up/downtrend snapshot), sma50_vs_sma200 (major trend shifts), adx_14p (trend vs range).
– Volatility: atr_pct_14p (normalized volatility for fair comparison).
– Oscillator: rsi_14p, stochrsi_* (overbought/oversold context).
– Heuristics: volatility_consistency, max_daily_spike_pct, volume_concentration_pct (risk filters against flash moves and pumpy volume).
Backtesting engine: fast, batched, reproducible
Take a saved screener result, run a strategy (or a few variants) across a slate of symbols in one go, and get a report you can trust. Launch runs directly from any saved scan or from an explicit symbol list. The engine keeps plumbing aligned — timeframes, warm-ups, symbol normalization — so comparisons are apples-to-apples. Each run writes expected artifacts: per-trade ledger, equity and drawdown series, exit-reason attribution, and a portfolio roll-up for multi-market tests.
Speed comes from caching historical data locally in columnar Parquet, JIT-compiling indicator math with Numba, and avoiding recomputation when only filters or parameter tweaks change. In practice, scanning candidates and retesting strategy variants becomes a quick loop.
Reproducibility is first-class. Each report records which screener produced the candidates (name, saved definition, timestamp), which strategy or alias ran, the exact parameters, the data window, and the fee/slippage model. CLI scenario files let you declare a base config and small, explicit overrides for symbols, strategies, or params — A/B/C reads like a lab notebook, not a pile of screenshots.
Two common shapes of systematic trading are covered:
– Directional systems (trend, mean reversion, breakouts): fixed historical windows with return, Sharpe/Sortino, drawdown depth/duration, hit rate and average trade stats, plus exit-reason breakdowns.
– Inventory-carrying or market-neutral systems (grids): continuous evaluation tracking compounding and inventory explicitly.
Default execution model: included Gunbot strategies generally enter and exit on candle open to stay realistic in backtests and avoid intra-bar fantasy fills.
Strategy library: familiar archetypes, easy to tinker
Built-in strategies cover what most traders actually use, so the focus stays on where and how to trade rather than reinventing entry signals.
Mean-Reversion:
– RSI_Reversion (oversold buys with ATR stop)
– BB_Reversion (fade band excursions)
– Stochastic_Reversion
– A combo that requires oscillator agreement and exits at fixed ATR multiples
Trend Following:
– EMACross
– MACD_Cross
– Supertrend_Follower (indicator line used as trailing stop)
– Heikin-Ashi variant to smooth noise
Volatility and Breakout:
– Donchian_Breakout
– Keltner_Squeeze_Breakout to separate real expansions from noise
Market-Neutral:
– Grid_Strategy designed for volatility harvesting with per-pair compounding logic
Hybrid and Adaptive:
– “Buy the dip in an uptrend” (mean reversion gated by a slow-MA trend filter)
– Dynamic_Momentum_Optimizer that retunes to recent conditions
Scope note: included strategies are not 1:1 emulations of Gunbot’s native strategies. They are a clean suite of technical approaches that are transparent, auditable, and benchmarkable.
For strategy developers: inside a gunbot quant js file
Strategies are plain JavaScript for compatibility with Gunbot’s custom strategy runtime:
https://www.gunbot.com/support/docs/custom-strategies/what-are-custom-strategies/
They are self-contained and readable.
Annotated structure of rsi_reversion.js:
/*
* Gunbot Quant Strategy: RSI_Reversion
* Summary of logic + configurable parameters.
* Parsed by the UI to populate help text.
*/
// Persistent, per-pair data store required by Gunbot.
gb.data.pairLedger.customStratStore = gb.data.pairLedger.customStratStore || {};
/* – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
* STATE INITIALIZATION: The strategy’s memory.
* – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – */
const store = gb.data.pairLedger.customStratStore;
if (typeof store.state !== “string”) store.state = “IDLE”; // “IDLE” | “IN_POSITION”
if (typeof store.stopPrice !== “number”) store.stopPrice = 0;
// … other state vars
/* – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
* INDICATORS: Self-contained TA functions.
* – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – */
const indicator_helpers = {
rsi: function (source, length) { /* … */ },
atr: function (high, low, close, length) { /* … */ }
};
/* – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
* ORDER HANDLERS: Thin wrappers for Gunbot’s methods.
* – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – */
const buyMarket = async (amount, exchange, pair) => { /* … gb.method.buyMarket … */ };
const sellMarket = async (amount, exchange, pair) => { /* … gb.method.sellMarket … */ };
/* – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
* STATE RECONCILIATION: Sync strategy state with reality.
* – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – */
function reconcileState() {
// Check gb.data.gotBag and gb.data.openOrders to determine position status,
// then update store.state accordingly (handles restarts/manual trades).
}
/* – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
* TRADING DECISION: Core logic.
* – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – */
async function decideTrade() {
reconcileState();
// 1) Read parameters from config (whatstrat)
const rsiPeriod = parseFloat(whatstrat.GQ_RSI_REVERSION_PERIOD || 14);
// …
// 2) Calculate indicators
const rsiValues = indicator_helpers.rsi(candlesClose, rsiPeriod);
const rsi = rsiValues[iLast];
// 3) Optional UI extras
gb.data.pairLedger.sidebarExtras = [{ label: “RSI Value”, value: rsi.toFixed(2) }];
// 4) State machine
if (store.state === “IDLE”) {
const wantToEnter = rsi < rsiOversold;
if (wantToEnter) await buyMarket(costQuote, exchangeName, pairName);
} else if (store.state === “IN_POSITION”) {
const wantToExit = rsi > rsiOverbought || ask < store.stopPrice;
if (wantToExit) await sellMarket(quoteBalance, exchangeName, pairName);
}
}
/* – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
* DRIVER: Entry point called by Gunbot on every tick.
* – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – */
await decideTrade();
Optional: Gunbot handoff and benchmarking
Everything above is useful even without Gunbot. With Gunbot, the loop tightens: after a batch test, push the winning configuration directly to your Gunbot instance. The tool handles mapping research symbols to Gunbot notation, creating the pair and strategy, and sending the exact parameters you tested.
Benchmarking answers a simple question: is this still the best place to run this setup? Compare your live strategy against the rest of the eligible market with the same logic. If rankings show a better candidate, rotate before lag turns into losses.
CLI for repeatable experiments
Prefer scripting? Use the CLI. Define a base configuration and a list of scenarios that override only what’s different.
Example: test two RSI_Reversion configs against a default EMACross on BTCUSDT.
1) Open gunbot_quant/config/scenarios.py
2) Add a dictionary to SCENARIOS:
{
“name”: “Multi_RSI_vs_EMACross_BTC”,
“params”: {
“EXCHANGE”: “binance”,
“TIMEFRAME”: “4h”,
“BACKTEST_START_DATE”: get_date_relative_to_now(days=365),
“SYMBOL_SELECTION_METHOD”: “EXPLICIT_LIST”,
“SYMBOLS”: [“BTCUSDT”],
“STRATEGIES”: [
{
“name”: “RSI_Reversion”,
“alias”: “RSI_Sensitive_Config”,
“params”: {
“GQ_RSI_REVERSION_PERIOD”: 10,
“GQ_RSI_REVERSION_OVERSOLD”: 25
}
},
{
“name”: “RSI_Reversion”,
“alias”: “RSI_Conservative_Config”,
“params”: {
“GQ_RSI_REVERSION_PERIOD”: 21,
“GQ_RSI_REVERSION_OVERSOLD”: 35,
“GQ_RSI_REVERSION_ATR_MULT”: 3.0
}
},
“EMACross”
]
}
}
3) Run the scenario:
python -m gunbot_quant.cli.main run Multi_RSI_vs_EMACross_BTC
The engine produces a single report comparing all three tests. All reports are viewable in the GQ frontend. This explicit approach supports long-term, systematic research.
Limitations
No tool can promise winners. The screener doesn’t divine tomorrow’s breakout, and the backtester isn’t a time machine; it reflects the rules you provided over the historical window you chose. Liquidity filters reduce but don’t eliminate execution risk; risk-adjusted metrics illuminate quality but don’t guarantee persistence.
Backtesting history is limited by exchange candle data availability.
Warning about overfitting: batch testing makes it easy to try hundreds of variations. Don’t turn that into parameter fishing. Lock a baseline, evaluate across markets and regimes, and only promote changes that improve risk-adjusted metrics and drawdown behavior — not just headline returns.
Wrap up
Gunbot Quant provides saved, algo-first market screeners combined with batched backtests — and, if desired, lets those exact tested configurations go live in one click in Gunbot.
It runs locally, is open-source under MIT, and is extensible.
Repository: https://github.com/GuntharDeNiro/gunbot-quant
Website: https://www.gunbot.com
Gunbot Quant: A Standalone, Open-Source Tool for Algorithmic Traders was originally published in Mastering Gunbot: Tips and Tutorials from gunbot.com on Medium, where people are continuing the conversation by highlighting and responding to this story.
Mastering Gunbot: Tips and Tutorials from gunbot.com – Medium


