Skip to content
Disclaimer: These examples are for educational and demonstration purposes only. They are not ready-to-use, profitable trading strategies

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;
}