UNPKG

@dendaio/n8n-nodes-collection

Version:

🚀 Comprehensive n8n node collection for financial analysis and automation. Features 55+ technical indicators (RSI, MACD, Bollinger Bands), 32+ candlestick patterns (Doji, Hammer, Engulfing), derivative statistics (Open Interest, Funding Rate, Long/Short

326 lines • 14.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TechnicalChart = void 0; const n8n_workflow_1 = require("n8n-workflow"); const puppeteer_1 = __importDefault(require("puppeteer")); class TechnicalChart { constructor() { this.description = { displayName: 'Technical Chart', name: 'technicalChart', icon: 'file:icon.svg', group: ['transform'], version: 1, description: 'Generate technical charts using remote browser and save as images', defaults: { name: 'Technical Chart', }, inputs: ["main"], outputs: ["main"], properties: [ { displayName: 'Browser WebSocket Endpoint', name: 'browserWSEndpoint', type: 'string', default: 'ws://localhost:3000', description: 'WebSocket endpoint for the remote browser', required: true, noDataExpression: true, }, { displayName: 'TradingView Endpoint', name: 'tradingviewEndpoint', type: 'string', default: 'https://www.tradingview.com/chart', description: 'TradingView chart endpoint URL', required: true, noDataExpression: true, }, { displayName: 'Symbol', name: 'symbol', type: 'string', default: 'BTC/USDT', description: 'Trading pair symbol (e.g., BTC/USDT, ETH/USDT)', required: true, noDataExpression: true, }, { displayName: 'Timeframe', name: 'timeframe', type: 'options', options: [ { name: '1 Day', value: '1d' }, { name: '1 Hour', value: '1h' }, { name: '1 Minute', value: '1m' }, { name: '1 Month', value: '1M' }, { name: '1 Week', value: '1w' }, { name: '12 Hours', value: '12h' }, { name: '15 Minutes', value: '15m' }, { name: '2 Hours', value: '2h' }, { name: '30 Minutes', value: '30m' }, { name: '4 Hours', value: '4h' }, { name: '5 Minutes', value: '5m' }, { name: '6 Hours', value: '6h' }, { name: '8 Hours', value: '8h' }, ], default: '1h', noDataExpression: true, }, { displayName: 'Theme', name: 'theme', type: 'options', options: [ { name: 'Light', value: 'light' }, { name: 'Dark', value: 'dark' }, ], default: 'light', noDataExpression: true, }, { displayName: 'Chart Width', name: 'width', type: 'number', typeOptions: { minValue: 800, maxValue: 3840, }, default: 1920, description: 'Width of the chart in pixels', noDataExpression: true, }, { displayName: 'Chart Height', name: 'height', type: 'number', typeOptions: { minValue: 600, maxValue: 2160, }, default: 1080, description: 'Height of the chart in pixels', noDataExpression: true, }, { displayName: 'Layout', name: 'layout', type: 'string', default: '', description: 'Chart layout identifier', noDataExpression: true, }, { displayName: 'Study', name: 'study', type: 'string', default: '', description: 'Technical analysis study identifier', noDataExpression: true, }, { displayName: 'Market', name: 'market', type: 'options', options: [ { name: 'Futures', value: 'futures' }, { name: 'Spot', value: 'spot' }, ], default: 'futures', description: 'Market type', noDataExpression: true, }, { displayName: 'Output Options', name: 'outputOptions', type: 'collection', placeholder: 'Add Output Option', default: {}, options: [ { displayName: 'Include Base64', name: 'includeBase64', type: 'boolean', default: true, description: 'Whether to include base64 data in the output', }, { displayName: 'Wait for Chart Load', name: 'waitForChartLoad', type: 'number', typeOptions: { minValue: 1000, maxValue: 30000, }, default: 5000, description: 'Additional wait time in milliseconds for chart to fully load', noDataExpression: true, }, ], }, { displayName: 'Advanced Options', name: 'advancedOptions', type: 'collection', placeholder: 'Add Advanced Option', default: {}, options: [ { displayName: 'Ignore HTTPS Errors', name: 'ignoreHttpsErrors', type: 'boolean', default: false, description: 'Whether to ignore HTTPS errors', }, { displayName: 'Timeout', name: 'timeout', type: 'number', typeOptions: { minValue: 10000, maxValue: 120000, }, default: 30000, description: 'Page load timeout in milliseconds', noDataExpression: true, }, { displayName: 'User Agent', name: 'userAgent', type: 'string', default: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', description: 'Custom user agent string', noDataExpression: true, }, ], }, ], }; } async execute() { const items = this.getInputData(); const returnData = []; for (let i = 0; i < items.length; i++) { try { const browserWSEndpoint = this.getNodeParameter('browserWSEndpoint', i); const tradingviewEndpoint = this.getNodeParameter('tradingviewEndpoint', i); const symbol = this.getNodeParameter('symbol', i); const timeframe = this.getNodeParameter('timeframe', i); const theme = this.getNodeParameter('theme', i); const width = this.getNodeParameter('width', i); const height = this.getNodeParameter('height', i); const layout = this.getNodeParameter('layout', i); const study = this.getNodeParameter('study', i); const market = this.getNodeParameter('market', i); const outputOptions = this.getNodeParameter('outputOptions', i, {}); const advancedOptions = this.getNodeParameter('advancedOptions', i, {}); if (!browserWSEndpoint) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Browser WebSocket endpoint is required'); } if (!tradingviewEndpoint) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'TradingView endpoint is required'); } if (!symbol) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Symbol is required'); } const includeBase64 = outputOptions.includeBase64 !== false; const waitForChartLoad = outputOptions.waitForChartLoad || 5000; const userAgent = advancedOptions.userAgent || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'; const timeout = advancedOptions.timeout || 30000; const ignoreHttpsErrors = advancedOptions.ignoreHttpsErrors === true; const browser = await puppeteer_1.default.connect({ browserWSEndpoint, ignoreHTTPSErrors: ignoreHttpsErrors, }); const page = await browser.newPage(); await page.setViewport({ width, height, deviceScaleFactor: 1, isMobile: false, }); await page.setUserAgent(userAgent); await page.setExtraHTTPHeaders({ 'Accept-Language': 'en-US,en;q=0.9', 'Accept-Encoding': 'gzip, deflate, br', Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', }); page.setDefaultTimeout(timeout); page.setDefaultNavigationTimeout(timeout); let chartUrl = `${tradingviewEndpoint}/?theme=${theme}&symbol=${symbol}&timeframe=${timeframe}`; if (layout) { chartUrl += `&layout=${encodeURIComponent(layout)}`; } if (study) { chartUrl += `&study=${encodeURIComponent(study)}`; } if (market) { chartUrl += `&market=${encodeURIComponent(market)}`; } const gotoOptions = { waitUntil: ['domcontentloaded', 'networkidle2'], timeout, }; await page.goto(chartUrl, gotoOptions); if (waitForChartLoad > 0) { await new Promise((resolve) => setTimeout(resolve, waitForChartLoad)); } const imageData = (await page.evaluate('saveChartToBase64()')); if (!imageData) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Failed to get chart data from saveChartToBase64 function'); } const base64Data = imageData.replace(/^data:image\/[^;]+;base64,/, ''); const outputData = { success: true, symbol, timeframe, theme, layout, study, market, chartUrl, dimensions: { width, height, }, chartImage: imageData, timestamp: new Date().toISOString(), metadata: { browserWSEndpoint, tradingviewEndpoint, userAgent, timeout, ignoreHttpsErrors, }, }; if (includeBase64) { outputData.base64Data = base64Data; } await browser.close(); returnData.push({ json: outputData, }); } catch (error) { if (this.continueOnFail()) { returnData.push({ json: { success: false, error: error instanceof Error ? error.message : 'Unknown error occurred', timestamp: new Date().toISOString(), }, }); continue; } throw error; } } return [returnData]; } } exports.TechnicalChart = TechnicalChart; //# sourceMappingURL=TechnicalChart.node.js.map