Skip to main content

Time Series Forecast & Balance of Power

This strategy involves using two technical indicators, the Time Series Forecast (TSF) and the Balance of Power (BOP), to generate buy and sell signals.

The TSF is a mathematical formula that uses historical prices to predict future prices. The indicator plots a line on the chart that shows the predicted price trend, allowing traders to identify potential changes in price direction.

The BOP is an oscillator that measures the strength of buyers and sellers in the market. It compares the closing price with the range between the high and low prices of the security, providing an indication of the level of bullish or bearish pressure in the market.

When the TSF line crosses above the current price and the BOP is positive, this may indicate a buy signal. Conversely, when the TSF line crosses below the current price and the BOP is negative, this may indicate a sell 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 Time Series Forecast (TSF) indicator
function tsf(period) {
const prices = gb.data.candlesClose.slice(-period);
const sumX = (period * (period + 1)) / 2;
const sumY = prices.reduce((a, b, i) => a + b * (i + 1), 0);
const sumXY = prices.reduce((a, b, i) => a + b * (i + 1) * (period - i), 0);
const sumX2 = (period * (period + 1) * (2 * period + 1)) / 6;
const slope = (period * sumXY - sumX * sumY) / (period * sumX2 - sumX ** 2);
const intercept = (sumY - slope * sumX) / period;
return slope * (period + 1) + intercept;
}

// calculate Balance of Power (BOP) indicator
function bop() {
const high = gb.data.candlesHigh.slice(-1)[0];
const low = gb.data.candlesLow.slice(-1)[0];
const close = gb.data.candlesClose.slice(-1)[0];
const volume = gb.data.candlesVolume.slice(-1)[0];
return (close - low) / (high - low) * volume;
}

// log indicators for debugging purposes
console.log(`TSF: ${tsf(10)}, BOP: ${bop()}`);

if (enoughTimePassed) {
const buyConditions = tsf(10) > gb.data.candlesClose.slice(-1)[0] && bop() > 0 && !gb.data.gotBag;
const sellConditions = tsf(10) < gb.data.candlesClose.slice(-1)[0] && bop() < 0 && gb.data.gotBag;

// fire orders when conditions are met
if (buyConditions) {
const buyAmount = gb.data.baseBalance * 0.95 / gb.data.ask; // use 95% of base balance to avoid dust
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