Skip to main content

Range trading strategy

This range trading strategy uses the Relative Strength Index (RSI) and Bollinger Bands to target price moves within a defined range. The RSI gauges momentum to flag overbought or oversold conditions, while Bollinger Bands define upper and lower range boundaries based on volatility.

Entry signals occur when the RSI is at an extreme (overbought or oversold) and price is near the corresponding Bollinger Band. Exit signals occur when price is near a band but the RSI is no longer at an extreme.

tip

This example strategy is machine generated using Gunbot AI. Review its behavior carefully in a simulated crypto trading bot instance before using parts of this code in production.

// initialize customStratStore within pairLedger object
gb.data.pairLedger.customStratStore = gb.data.pairLedger.customStratStore || {};

// forced wait time reduces risk of double orders
function checkTime() {
return !gb.data.pairLedger.customStratStore.timeCheck || typeof gb.data.pairLedger.customStratStore.timeCheck !== "number"
? (gb.data.pairLedger.customStratStore.timeCheck = Date.now(), false)
: (Date.now() - gb.data.pairLedger.customStratStore.timeCheck > 8000);
}
const enoughTimePassed = checkTime();

// set timestamp for checkTime in next round
const setTimestamp = () => gb.data.pairLedger.customStratStore.timeCheck = Date.now();

// calculate RSI
const rsi = gb.data.rsi;
console.log("RSI:", rsi);

// calculate Bollinger Bands
const bbPeriod = 20;
const bbStdDev = 2;
const bbUpper = gb.data.candlesClose.slice(-bbPeriod).reduce((acc, val) => acc + val, 0) / bbPeriod + bbStdDev * gb.data.candlesClose.slice(-bbPeriod).reduce((acc, val) => acc + Math.pow(val - (gb.data.candlesClose.slice(-bbPeriod).reduce((acc, val) => acc + val, 0) / bbPeriod), 2), 0) / bbPeriod;
const bbLower = gb.data.candlesClose.slice(-bbPeriod).reduce((acc, val) => acc + val, 0) / bbPeriod - bbStdDev * gb.data.candlesClose.slice(-bbPeriod).reduce((acc, val) => acc + Math.pow(val - (gb.data.candlesClose.slice(-bbPeriod).reduce((acc, val) => acc + val, 0) / bbPeriod), 2), 0) / bbPeriod;
console.log("BB Upper:", bbUpper);
console.log("BB Lower:", bbLower);

if (enoughTimePassed) {
// calculate buy and sell conditions
const buyConditions = rsi < 30 && gb.data.candlesClose.slice(-1)[0] < bbLower && !gb.data.gotBag;
const sellConditions = rsi > 70 && gb.data.candlesClose.slice(-1)[0] > bbUpper && gb.data.gotBag;

// fire orders when conditions are met
if (buyConditions) {
const buyAmount = parseFloat(gb.data.pairLedger.whatstrat.TRADING_LIMIT) / gb.data.bid;
gb.method.buyMarket(buyAmount, gb.data.pairName);
setTimestamp();
console.log("Buy order placed.");
} else if (sellConditions) {
gb.method.sellMarket(gb.data.quoteBalance, gb.data.pairName);
setTimestamp();
console.log("Sell order placed.");
}
} else {
console.log("Not enough time has passed since last order.");
}

// Code is machine generated, review it and run in simulator mode first