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), automated trading strategies, RSS feed processing, and OAuth2 v

486 lines • 21.5 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.TrendStrategy = void 0; const n8n_workflow_1 = require("n8n-workflow"); const indicatorts = __importStar(require("indicatorts")); class TrendStrategy { constructor() { this.description = { displayName: 'Trend Strategy', name: 'trendStrategy', icon: 'file:icon.svg', group: ['transform'], version: 1, description: 'Execute trend trading strategies using the indicatorts library', defaults: { name: 'Trend Strategy', }, inputs: ["main"], outputs: ["main"], properties: [ { displayName: 'Strategy', name: 'strategy', type: 'options', options: [ { name: 'Absolute Price Oscillator Strategy', value: 'absolutePriceOscillatorStrategy', description: 'Strategy based on Absolute Price Oscillator trend indicator', }, { name: 'Aroon Strategy', value: 'aroonStrategy', description: 'Strategy based on Aroon trend indicator', }, { name: 'Balance of Power Strategy', value: 'balanceOfPowerStrategy', description: 'Strategy based on Balance of Power indicator', }, { name: 'Chande Forecast Oscillator Strategy', value: 'chandeForecastOscillatorStrategy', description: 'Strategy based on Chande Forecast Oscillator', }, { name: 'KDJ Strategy', value: 'kdjStrategy', description: 'Strategy based on KDJ (Random Index) indicator', }, { name: 'MACD Strategy', value: 'macdStrategy', description: 'Strategy based on Moving Average Convergence Divergence', }, { name: 'Parabolic SAR Strategy', value: 'parabolicSarStrategy', description: 'Strategy based on Parabolic SAR indicator', }, { name: 'Typical Price Strategy', value: 'typicalPriceStrategy', description: 'Strategy based on Typical Price indicator', }, { name: 'Vortex Strategy', value: 'vortexStrategy', description: 'Strategy based on Vortex indicator', }, { name: 'VWMA Strategy', value: 'vwmaStrategy', description: 'Strategy based on Volume Weighted Moving Average', }, ], default: 'macdStrategy', noDataExpression: true, }, { displayName: 'OHLCV Data', name: 'ohlcvData', type: 'string', default: '={{ $json.ohlcv }}', description: 'JSON string containing OHLCV data array', }, { displayName: 'Date Data', name: 'dateData', type: 'string', default: '={{ $json.dates }}', description: 'JSON string containing date array (optional, will use index if not provided)', }, { displayName: 'APO Fast Period', name: 'apoFast', type: 'number', default: 12, description: 'Fast period for Absolute Price Oscillator calculation', displayOptions: { show: { strategy: ['absolutePriceOscillatorStrategy'], }, }, }, { displayName: 'APO Slow Period', name: 'apoSlow', type: 'number', default: 26, description: 'Slow period for Absolute Price Oscillator calculation', displayOptions: { show: { strategy: ['absolutePriceOscillatorStrategy'], }, }, }, { displayName: 'Aroon Period', name: 'aroonPeriod', type: 'number', default: 25, description: 'Period for Aroon indicator calculation', displayOptions: { show: { strategy: ['aroonStrategy'], }, }, }, { displayName: 'KDJ R Period', name: 'kdjRPeriod', type: 'number', default: 9, description: 'R period for KDJ indicator calculation', displayOptions: { show: { strategy: ['kdjStrategy'], }, }, }, { displayName: 'KDJ K Period', name: 'kdjKPeriod', type: 'number', default: 3, description: 'K period for KDJ indicator calculation', displayOptions: { show: { strategy: ['kdjStrategy'], }, }, }, { displayName: 'KDJ D Period', name: 'kdjDPeriod', type: 'number', default: 3, description: 'D period for KDJ indicator calculation', displayOptions: { show: { strategy: ['kdjStrategy'], }, }, }, { displayName: 'MACD Fast Period', name: 'macdFast', type: 'number', default: 12, description: 'Fast period for MACD calculation', displayOptions: { show: { strategy: ['macdStrategy'], }, }, }, { displayName: 'MACD Slow Period', name: 'macdSlow', type: 'number', default: 26, description: 'Slow period for MACD calculation', displayOptions: { show: { strategy: ['macdStrategy'], }, }, }, { displayName: 'MACD Signal Period', name: 'macdSignal', type: 'number', default: 9, description: 'Signal period for MACD calculation', displayOptions: { show: { strategy: ['macdStrategy'], }, }, }, { displayName: 'PSAR Step', name: 'psarStep', type: 'number', default: 0.02, description: 'Step value for Parabolic SAR calculation', displayOptions: { show: { strategy: ['parabolicSarStrategy'], }, }, }, { displayName: 'PSAR Max', name: 'psarMax', type: 'number', default: 0.2, description: 'Maximum value for Parabolic SAR calculation', displayOptions: { show: { strategy: ['parabolicSarStrategy'], }, }, }, { displayName: 'Vortex Period', name: 'vortexPeriod', type: 'number', default: 14, description: 'Period for Vortex indicator calculation', displayOptions: { show: { strategy: ['vortexStrategy'], }, }, }, { displayName: 'VWMA Period', name: 'vwmaPeriod', type: 'number', default: 20, description: 'Period for Volume Weighted Moving Average calculation', displayOptions: { show: { strategy: ['vwmaStrategy'], }, }, }, { displayName: 'Options', name: 'options', type: 'collection', placeholder: 'Add Option', default: {}, options: [ { displayName: 'Return Type', name: 'returnType', type: 'options', options: [ { name: 'Actions Only', value: 'actions', description: 'Return only the strategy actions (BUY/SELL/HOLD)', }, { name: 'With Metadata', value: 'metadata', description: 'Return actions with additional metadata and analysis', }, ], default: 'actions', }, { displayName: 'Include Gains Calculation', name: 'includeGains', type: 'boolean', default: false, description: 'Whether to calculate and include strategy gains based on actions', displayOptions: { show: { returnType: ['metadata'], }, }, }, ], }, ], }; } async execute() { const items = this.getInputData(); const returnData = []; for (let i = 0; i < items.length; i++) { try { const strategy = this.getNodeParameter('strategy', i); const ohlcvDataString = this.getNodeParameter('ohlcvData', i); const dateDataString = this.getNodeParameter('dateData', i, ''); const options = this.getNodeParameter('options', i, {}); let ohlcvData; try { ohlcvData = JSON.parse(ohlcvDataString); } catch (error) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to parse OHLCV data: ${error instanceof Error ? error.message : 'Unknown error'}`); } if (!Array.isArray(ohlcvData) || ohlcvData.length === 0) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'OHLCV data must be a non-empty array'); } let dates = []; if (dateDataString) { try { const dateArray = JSON.parse(dateDataString); if (Array.isArray(dateArray)) { dates = dateArray.map((date) => new Date(date)); } } catch (error) { console.warn('Failed to parse date data, using index-based dates'); } } if (dates.length === 0) { dates = ohlcvData.map((_, index) => new Date(Date.now() - (ohlcvData.length - index - 1) * 24 * 60 * 60 * 1000)); } const opens = ohlcvData.map((candle) => candle[0]); const highs = ohlcvData.map((candle) => candle[1]); const lows = ohlcvData.map((candle) => candle[2]); const closes = ohlcvData.map((candle) => candle[3]); const volumes = ohlcvData.map((candle) => candle[4] || 0); const asset = { dates, openings: opens, highs, lows, closings: closes, volumes, }; let actions; let config = {}; switch (strategy) { case 'absolutePriceOscillatorStrategy': config.fast = this.getNodeParameter('apoFast', i, 12); config.slow = this.getNodeParameter('apoSlow', i, 26); actions = indicatorts.absolutePriceOscillatorStrategy(asset, config); break; case 'aroonStrategy': config.period = this.getNodeParameter('aroonPeriod', i, 25); actions = indicatorts.aroonStrategy(asset, config); break; case 'balanceOfPowerStrategy': actions = indicatorts.balanceOfPowerStrategy(asset); break; case 'chandeForecastOscillatorStrategy': actions = indicatorts.chandeForecastOscillatorStrategy(asset); break; case 'kdjStrategy': config.rPeriod = this.getNodeParameter('kdjRPeriod', i, 9); config.kPeriod = this.getNodeParameter('kdjKPeriod', i, 3); config.dPeriod = this.getNodeParameter('kdjDPeriod', i, 3); actions = indicatorts.kdjStrategy(asset, config); break; case 'macdStrategy': config.fast = this.getNodeParameter('macdFast', i, 12); config.slow = this.getNodeParameter('macdSlow', i, 26); config.signal = this.getNodeParameter('macdSignal', i, 9); actions = indicatorts.macdStrategy(asset, config); break; case 'parabolicSarStrategy': config.step = this.getNodeParameter('psarStep', i, 0.02); config.max = this.getNodeParameter('psarMax', i, 0.2); actions = indicatorts.parabolicSARStrategy(asset, config); break; case 'typicalPriceStrategy': actions = indicatorts.typicalPriceStrategy(asset); break; case 'vortexStrategy': config.period = this.getNodeParameter('vortexPeriod', i, 14); actions = indicatorts.vortexStrategy(asset, config); break; case 'vwmaStrategy': config.period = this.getNodeParameter('vwmaPeriod', i, 20); actions = indicatorts.vwmaStrategy(asset, config); break; default: throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unsupported strategy: ${strategy}`); } const outputData = { strategy, parameters: config, actions: actions.map((action) => { switch (action) { case indicatorts.Action.BUY: return 'BUY'; case indicatorts.Action.SELL: return 'SELL'; case indicatorts.Action.HOLD: return 'HOLD'; default: return 'UNKNOWN'; } }), actionValues: actions, }; if (options.returnType === 'metadata') { const buyCount = actions.filter((a) => a === indicatorts.Action.BUY).length; const sellCount = actions.filter((a) => a === indicatorts.Action.SELL).length; const holdCount = actions.filter((a) => a === indicatorts.Action.HOLD).length; const metadata = { totalActions: actions.length, buySignals: buyCount, sellSignals: sellCount, holdSignals: holdCount, buyPercentage: ((buyCount / actions.length) * 100).toFixed(2) + '%', sellPercentage: ((sellCount / actions.length) * 100).toFixed(2) + '%', holdPercentage: ((holdCount / actions.length) * 100).toFixed(2) + '%', inputLength: ohlcvData.length, calculationTimestamp: new Date().toISOString(), }; outputData.metadata = metadata; if (options.includeGains) { try { const gains = indicatorts.applyActions(closes, actions); outputData.gains = gains; outputData.totalGain = gains[gains.length - 1] || 0; metadata.totalGain = gains[gains.length - 1] || 0; } catch (error) { outputData.gainsError = error instanceof Error ? error.message : 'Unknown error'; } } } returnData.push({ json: outputData, }); } catch (error) { if (this.continueOnFail()) { returnData.push({ json: { error: error instanceof Error ? error.message : 'Unknown error occurred', }, }); continue; } throw error; } } return [returnData]; } } exports.TrendStrategy = TrendStrategy; //# sourceMappingURL=TrendStrategy.node.js.map