Mathieu2301 / TradingView-API

📈 Get real-time stocks from TradingView
1.47k stars 332 forks source link

"Calculation timed out" error and account bans #179

Open vojtalousa opened 1 year ago

vojtalousa commented 1 year ago

Hello, I am trying to backtest a private strategy while changing a parameter to a range of values on a range of timeframes. Once it tests a configuration (e.g. timeframe 5 with parameter 10) it saves it and at the and it finds the one that's the most profitable. In total it will be testing around 100 timeframes and 60 parameter configurations so 6000 combinations. I'm having issues with "Calculation timed out. Remove the indicator and reapply it to the chart" errors and account bans.

This is the code I'm using: (a lot of the parts I deemed irrelevant were removed)

const client = new TradingView.Client({
    token: config.token,
    server: 'prodata'
});

const defaultIndicator = await TradingView.getIndicator(config.indicator)
const createIndicator = (sensitivity) => {
    const indicator = new TradingView.PineIndicator({
        pineId: defaultIndicator.pineId,
        pineVersion: defaultIndicator.pineVersion,
        description: defaultIndicator.description,
        shortDescription: defaultIndicator.shortDescription,
        inputs: defaultIndicator.inputs,
        plots: defaultIndicator.plots,
        script: defaultIndicator.script,
    })
    indicator.setOption('Sensitivity', sensitivity);
    return indicator;
}

const createChart = async () => {
    const chart = new client.Session.Chart();
    while (timeframes.length > 0) {
        const timeframe = timeframes.shift();
        chart.setMarket(market, { timeframe, range: 20000, type: config.chartType });
        await waitForLoad();

        const remainingSensitivities = [...sensitivities];
        const addStudy = () => new Promise((resolve) => {
            let currentSensitivity = remainingSensitivities.shift();
            const study = new chart.Study(createIndicator(currentSensitivity));
            let lastStudyUpdate = {};
            study.onUpdate(() => {
                const profitPercent = performance?.all?.netProfitPercent * 100;
                const drawdownPercent = performance?.maxStrategyDrawDownPercent * 100;
                if (!profitPercent || !drawdownPercent) return

                const resultsChanged = !util.isDeepStrictEqual(lastStudyUpdate, { profitPercent, drawdownPercent });
                lastStudyUpdate = { profitPercent, drawdownPercent };
                if (resultsChanged) {
                    results.push({ timeframe, sensitivity: currentSensitivity, profitPercent, drawdownPercent })
                    if (remainingSensitivities.length > 0) {
                        currentSensitivity = remainingSensitivities.shift();
                        study.setIndicator(createIndicator(currentSensitivity));
                    } else {
                        study.remove();
                        resolve();
                    }
                }
            });
        })
        await runAsync(addStudy, config.numStudies)
    }
    chart.delete();
}
await runAsync(createChart, config.numCharts)

So I'm asking for help with solving the aforementioned "Calculation timed out" issue and prevent account bans (they happen after testing around 4000 combinations; there aren't any ratelimits or warnings before the ban).