Skip to main content

Elder-Ray Index & Zig Zag indicator

This stratetgy uses two technical indicators, the Elder-Ray Index and the Zig Zag indicator, to generate entry and exit signals for trading.

The Elder-Ray Index is a momentum indicator that consists of two separate components, the Bull Power and Bear Power. Bull Power measures the strength of the bulls (buyers) in the market, while Bear Power measures the strength of the bears (sellers). The Elder-Ray Index is calculated by subtracting the exponential moving average (EMA) of Bear Power from the EMA of Bull Power.

The Zig Zag indicator is a trend-following indicator that helps to identify the direction of the trend by filtering out minor price movements. It does this by drawing lines between the high and low points of the price chart, only changing direction when the price moves a certain percentage or amount.

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 the Elder-Ray Index
function elderRayIndex() {
const high = gb.data.candlesHigh;
const low = gb.data.candlesLow;
const close = gb.data.candlesClose;
const ema13 = calculateEMA(13, close);
const ema26 = calculateEMA(26, close);
const bullPower = high.map((h, i) => h - ema13[i]);
const bearPower = low.map((l, i) => l - ema13[i]);
const elderRay = close.map((c, i) => {
const diff = ema13[i] - ema26[i];
return diff > 0 ? bullPower[i] / diff : bearPower[i] / Math.abs(diff);
});
return elderRay;
}

// calculate the Zig Zag indicator
function zigZag() {
const deviation = 0.05;
const pivotHigh = [];
const pivotLow = [];
let trend = "up";
let lastPivot = 0;
let currentHigh = 0;
let currentLow = 0;
for (let i = 0; i < gb.data.candlesClose.length; i++) {
if (gb.data.candlesHigh[i] >= currentHigh) {
currentHigh = gb.data.candlesHigh[i];
currentLow = gb.data.candlesLow[i];
if (trend === "down" && (currentHigh - currentLow) > (currentHigh - lastPivot) * deviation) {
pivotLow.push(lastPivot);
trend = "up";
lastPivot = currentLow;
currentHigh = 0;
currentLow = 0;
}
} else if (gb.data.candlesLow[i] <= currentLow) {
currentLow = gb.data.candlesLow[i];
currentHigh = gb.data.candlesHigh[i];
if (trend === "up" && (currentHigh - currentLow) > (lastPivot - currentLow) * deviation) {
pivotHigh.push(lastPivot);
trend = "down";
lastPivot = currentHigh;
currentHigh = 0;
currentLow = 0;
}
}
}
return { pivotHigh, pivotLow };
}

// calculate the Exponential Moving Average
function calculateEMA(period, data) {
const ema = [];
const multiplier = 2 / (period + 1);
let sma = data.slice(0, period).reduce((acc, val) => acc + val, 0) / period;
ema.push(sma);
for (let i = period; i < data.length; i++) {
const currentEMA = (data[i] - ema[i - period]) * multiplier + ema[i - period];
ema.push(currentEMA);
}
return ema;
}

// log all indicators
console.log("Elder-Ray Index:", elderRayIndex());
console.log("Zig Zag:", zigZag());

if (enoughTimePassed) {
const buyConditions = elderRayIndex()[elderRayIndex().length - 1] > 0 && zigZag().pivotLow.length > 0 && !gb.data.gotBag;
const sellConditions = elderRayIndex()[elderRayIndex().length - 1] < 0 && zigZag().pivotHigh.length > 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();
} else if (sellConditions) {
gb.method.sellMarket(gb.data.quoteBalance, gb.data.pairName);
setTimestamp();
}
}

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