Skip to main content

Range trading

The range trading strategy using Relative Strength Index (RSI) and Bollinger Bands is a trading approach that seeks to profit from price movements within a certain range. The strategy uses two technical indicators, the RSI and Bollinger Bands, to generate entry and exit signals for trades.

The RSI measures the momentum of the price movement of an asset over a certain period of time, indicating whether the asset is overbought or oversold. The Bollinger Bands, on the other hand, are a measure of volatility, indicating the upper and lower boundaries of a trading range based on standard deviations from the moving average of the asset price.

The strategy uses the RSI and Bollinger Bands to identify entry and exit signals for trades. When the RSI is at an extreme value (either overbought or oversold) and the price is near the upper or lower Bollinger Band, the strategy generates an entry signal. Conversely, when the RSI is not at an extreme value and the price is near the upper or lower Bollinger Band, the strategy generates an exit signal.

tip

This example strategy is machine generated using Gunbot AI. Review its behavior carefully in a simulated 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