Created
January 8, 2024 14:48
-
-
Save GuntharDeNiro/f4c4fe0fe21184fdb73a26cb075f9133 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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