Parabolic SAR strategy
This strategy is a short-term scalping approach that aims to capture small price moves using the Parabolic SAR and Commodity Channel Index (CCI) for entry and exit signals.
The same logic can be adapted into a parabolic trading strategy for trend-following tests. For parabolic SAR scalping, reduce position size and test more aggressively, because small timeframe signals can flip quickly.
Parabolic SAR (Stop and Reverse) is a trend-following indicator plotted as dots above or below price. Dots below price indicate a bullish trend, while dots above price indicate a bearish trend. The CCI identifies overbought and oversold conditions by comparing an asset’s average price to its moving average and standard deviation; high values signal overbought conditions, and low values signal oversold conditions.
In this strategy, Parabolic SAR and CCI are calculated manually rather than using built-in methods.
Overall, the strategy combines these indicators and includes a filter to avoid trading in directionless markets.
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 Parabolic SAR
function parabolicSAR(high, low, accelerationFactor, maxAccelerationFactor, prevSAR, prevEP, prevAF) {
let SAR = prevSAR;
let EP = prevEP;
let AF = prevAF;
if (prevSAR === null || prevEP === null || prevAF === null) {
SAR = low[0];
EP = high[0];
AF = accelerationFactor;
} else {
if (prevSAR < low[0]) {
SAR = prevSAR + prevAF * (prevEP - prevSAR);
SAR = Math.min(SAR, high[0]);
} else if (prevSAR > high[0]) {
SAR = prevSAR + prevAF * (prevEP - prevSAR);
SAR = Math.max(SAR, low[0]);
} else {
if (prevEP > high[0]) {
EP = high[0];
AF = Math.min(AF + accelerationFactor, maxAccelerationFactor);
} else if (prevEP < low[0]) {
EP = low[0];
AF = Math.min(AF + accelerationFactor, maxAccelerationFactor);
}
SAR = prevSAR + prevAF * (prevEP - prevSAR);
SAR = Math.min(SAR, high[0]);
SAR = Math.max(SAR, low[0]);
}
}
return [SAR, EP, AF];
}
// calculate Commodity Channel Index (CCI)
function cci(high, low, close, period) {
const typicalPrices = [];
for (let i = 0; i < period; i++) {
typicalPrices.push((high[i] + low[i] + close[i]) / 3);
}
const typicalPriceSMA = typicalPrices.reduce((a, b) => a + b, 0) / period;
const meanDeviation = typicalPrices.reduce((a, b) => a + Math.abs(b - typicalPriceSMA), 0) / period;
const cci = (typicalPrices[0] - typicalPriceSMA) / (0.015 * meanDeviation);
return cci;
}
// calculate indicators
const sar = parabolicSAR(gb.data.candlesHigh, gb.data.candlesLow, 0.02, 0.2, null, null, null)[0];
const cciValue = cci(gb.data.candlesHigh, gb.data.candlesLow, gb.data.candlesClose, 20);
// log indicators
console.log(`Parabolic SAR: ${sar}`);
console.log(`CCI: ${cciValue}`);
if (enoughTimePassed) {
const buyConditions = sar > gb.data.candlesClose[1] && cciValue < -100 && !gb.data.gotBag;
const sellConditions = sar < gb.data.candlesClose[1] && cciValue > 100 && 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