Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save GuntharDeNiro/f4c4fe0fe21184fdb73a26cb075f9133 to your computer and use it in GitHub Desktop.
Save GuntharDeNiro/f4c4fe0fe21184fdb73a26cb075f9133 to your computer and use it in GitHub Desktop.
/*
Create a trading strategy using the Choppiness Index and the Detrended Price Oscillator for entry and exit signals. Console log every indicator and trading conditions. Do not buy when there is a bag, do not sell when there is no bag.
*/
// Initialize customStratStore in pairLedger
gb.data.pairLedger.customStratStore ||= {};
// Choppiness Index calculation (not provided by default, so we calculate manually)
const calculateChoppinessIndex = (period = 14) => {
const high = gb.data.candlesHigh.slice(-period);
const low = gb.data.candlesLow.slice(-period);
const close = gb.data.candlesClose.slice(-period);
const trueRange = high.map((h, i) => h - low[i]);
const sumTrueRange = trueRange.reduce((acc, val) => acc + val, 0);
const atr = sumTrueRange / period;
const log10 = Math.log10;
const maxHigh = Math.max(...high);
const minLow = Math.min(...low);
const choppinessIndex = 100 * log10(sumTrueRange / (maxHigh - minLow)) / log10(period);
return choppinessIndex;
};
// Detrended Price Oscillator calculation (not provided by default, so we calculate manually)
const calculateDPO = (period = 20) => {
const priceArray = gb.data.candlesClose.slice(-period - Math.floor(period / 2) - 1);
const dpoArray = priceArray.map((price, index) => {
if (index >= period) {
const displacedPrice = priceArray[index - Math.floor(period / 2)];
const sma = priceArray.slice(index - period, index).reduce((acc, val) => acc + val, 0) / period;
return displacedPrice - sma;
}
return null;
}).filter(val => val !== null);
const dpo = dpoArray[dpoArray.length - 1];
return dpo;
};
// Ensure sufficient time has passed
const enoughTimePassed = (() => {
if (!gb.data.pairLedger.customStratStore.timeCheck || typeof gb.data.pairLedger.customStratStore.timeCheck !== "number") {
gb.data.pairLedger.customStratStore.timeCheck = Date.now();
return false;
}
return Date.now() - gb.data.pairLedger.customStratStore.timeCheck > 8000;
})();
// Set timestamp for the next round
const setTimestamp = () => gb.data.pairLedger.customStratStore.timeCheck = Date.now();
if (enoughTimePassed) {
// Calculate indicators
const choppinessIndex = calculateChoppinessIndex();
const dpo = calculateDPO();
// Log indicators
console.log(`Choppiness Index: ${choppinessIndex}`);
console.log(`Detrended Price Oscillator: ${dpo}`);
// Define buy and sell conditions
const buyConditions = !gb.data.gotBag && choppinessIndex < 61.8 && dpo > 0;
const sellConditions = gb.data.gotBag && choppinessIndex > 38.2 && dpo < 0;
// Log trading conditions
console.log(`Buy Conditions Met: ${buyConditions}`);
console.log(`Sell Conditions Met: ${sellConditions}`);
// Calculate buy amount using TRADING_LIMIT and bid price
const buyAmount = parseFloat(gb.data.pairLedger.whatstrat.TRADING_LIMIT) / gb.data.bid;
// Execute orders when conditions are met
if (buyConditions) {
gb.method.buyMarket(buyAmount, gb.data.pairName);
setTimestamp();
}
else if (sellConditions) {
gb.method.sellMarket(gb.data.baseBalance, gb.data.pairName);
setTimestamp();
}
}
// Code is machine generated, review it and run in simulator mode first
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment