Skip to main content

Swing trading with Bollinger Bands and MACD strategy

This swing trading strategy combines Bollinger Bands and MACD to generate entry and exit signals. Bollinger Bands gauge volatility for potential buy/sell zones, while MACD highlights momentum shifts. The script logs indicator values and trade conditions to make decisions traceable and easier to review.

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();

if (enoughTimePassed) {
// 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;
const bbMiddle = gb.data.candlesClose.slice(-bbPeriod).reduce((acc, val) => acc + val, 0) / bbPeriod;

// calculate MACD
const macdFastPeriod = 12;
const macdSlowPeriod = 26;
const macdSignalPeriod = 9;
const macdFast = gb.data.candlesClose.slice(-macdFastPeriod).reduce((acc, val) => acc + val, 0) / macdFastPeriod;
const macdSlow = gb.data.candlesClose.slice(-macdSlowPeriod).reduce((acc, val) => acc + val, 0) / macdSlowPeriod;
const macd = macdFast - macdSlow;
const macdSignal = gb.data.candlesClose.slice(-macdSignalPeriod).reduce((acc, val) => acc + val, 0) / macdSignalPeriod;
const macdHistogram = macd - macdSignal;

// log indicators
console.log(`Bollinger Bands: Upper: ${bbUpper}, Middle: ${bbMiddle}, Lower: ${bbLower}`);
console.log(`MACD: ${macd}, Signal: ${macdSignal}, Histogram: ${macdHistogram}`);

// set buy and sell conditions
const buyConditions = gb.data.candlesClose.slice(-2)[0] < bbLower && macdHistogram > 0 && !gb.data.gotBag;
const sellConditions = gb.data.candlesClose.slice(-2)[0] > bbUpper && macdHistogram < 0 && 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 at ${gb.data.bid}`);
} else if (sellConditions) {
gb.method.sellMarket(gb.data.quoteBalance, gb.data.pairName);
setTimestamp();
console.log(`Sell order placed at ${gb.data.ask}`);
}
}

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