Dynamic Auto-Recenter Grid Bot
Automatically builds buy/sell levels using Bollinger Bands and recent volatility. When price drifts away from the center or volatility changes, the grid recenters itself. Buys when price drops into the buy zone, sells when it rises into the sell zone.
When to use: Best for sideways, ranging markets where price oscillates around a middle value.
// Dynamic Auto-Recenter Grid Bot
const amount = "40%";const gridCount = 6;
let buyLevels = [];let sellLevels = [];let prevZone = null; // "buy", "sell", or null
function setup() { ind.add({ name: "bbands", alias: "bb", inputs: ["close"], options: { period: 20, stddev: 2 }, display: false });
ind.add({ name: "adx", alias: "adx", inputs: ["high", "low"], options: { period: 14 } });}
async function update() { const bb = ind.get("bb"); const adx = ind.get("adx"); const price = candle.close;
if (!bb || !bb.middle) return;
// Hard trend means new grid const needRecenter = price > bb.upper * 1.01 || price < bb.lower * 0.99 || adx > 30;
// --- Build / Rebuild Grid --- if (needRecenter || buyLevels.length === 0 || sellLevels.length === 0) { const step = (bb.upper - bb.lower) / gridCount;
buyLevels = []; sellLevels = [];
for (let i = 1; i <= gridCount; i++) { const buy = bb.middle - step * i; const sell = bb.middle + step * i; buyLevels.push(buy); sellLevels.push(sell); }
prevZone = null; } ta.plot('buyLevels', buyLevels, { type: 'Splines', props: { color: 'green' } }); ta.plot('sellLevels', sellLevels, { type: 'Splines', props: { color: 'red' } }); // Determine if price is in BUY or SELL region let zone = null;
if (price <= buyLevels[0]) { zone = "buy"; } else if (price >= sellLevels[0]) { zone = "sell"; } else { zone = "middle"; }
// First run → just store if (prevZone === null) { prevZone = zone; return; }
// Avoid trading during strong trends if (adx >= 25) return; // ---- BUY crossing ---- if (prevZone !== "buy" && zone === "buy") { await order.buy(null, amount); }
// ---- SELL crossing ---- if (prevZone !== "sell" && zone === "sell") { await order.sell(null, amount); }
prevZone = zone;}