@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
311 lines • 13 kB
JavaScript
;
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.GetOhlcv = void 0;
const n8n_workflow_1 = require("n8n-workflow");
const ccxt = __importStar(require("ccxt"));
class GetOhlcv {
constructor() {
this.description = {
displayName: 'Get OHLCV',
name: 'getOhlcv',
icon: 'file:icon.svg',
group: ['transform'],
version: 1,
description: 'Fetch OHLCV (Open, High, Low, Close, Volume) data from cryptocurrency exchanges',
defaults: {
name: 'Get OHLCV',
},
inputs: ["main"],
outputs: ["main"],
properties: [
{
displayName: 'Exchange',
name: 'exchange',
type: 'options',
options: [
{
name: 'Binance',
value: 'binance',
description: 'Binance exchange',
},
{
name: 'Bybit',
value: 'bybit',
description: 'Bybit exchange',
},
{
name: 'Gate',
value: 'gate',
description: 'Gate.io exchange',
},
{
name: 'Kraken',
value: 'kraken',
description: 'Kraken exchange',
},
{
name: 'Kucoin',
value: 'kucoin',
description: 'KuCoin exchange',
},
{
name: 'MEXC',
value: 'mexc',
description: 'MEXC exchange',
},
{
name: 'OKX',
value: 'okx',
description: 'OKX exchange',
},
],
default: 'binance',
noDataExpression: true,
},
{
displayName: 'Mode',
name: 'mode',
type: 'options',
options: [
{
name: 'Spot',
value: 'spot',
description: 'Spot trading',
},
{
name: 'Future',
value: 'future',
description: 'Futures trading',
},
],
default: 'spot',
noDataExpression: true,
},
{
displayName: 'Symbol',
name: 'symbol',
type: 'string',
default: 'BTC/USDT',
description: 'Trading pair symbol (e.g., BTC/USDT, ETH/USDT)',
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: '3 Days', value: '3d' },
{ name: '3 Minutes', value: '3m' },
{ 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: 'Limit',
name: 'limit',
type: 'number',
typeOptions: {
minValue: 1,
},
default: 50,
description: 'Max number of results to return',
noDataExpression: true,
},
{
displayName: 'Since',
name: 'since',
type: 'dateTime',
default: '',
description: 'Timestamp in ms to get OHLCV data since',
noDataExpression: true,
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add Option',
default: {},
options: [
{
displayName: 'API Key',
name: 'apiKey',
type: 'string',
typeOptions: { password: true },
default: '',
description: 'API key for the exchange (optional for public data)',
noDataExpression: true,
},
{
displayName: 'Include Timestamp',
name: 'includeTimestamp',
type: 'boolean',
default: true,
description: 'Whether to include timestamp in the output',
},
{
displayName: 'Password',
name: 'password',
type: 'string',
typeOptions: { password: true },
default: '',
description: 'Password for the exchange (optional for public data)',
noDataExpression: true,
},
{
displayName: 'Sandbox',
name: 'sandbox',
type: 'boolean',
default: false,
description: 'Whether to use sandbox/testnet',
},
{
displayName: 'Secret',
name: 'secret',
type: 'string',
typeOptions: { password: true },
default: '',
description: 'Secret key for the exchange (optional for public data)',
noDataExpression: true,
},
],
},
],
};
}
async execute() {
const items = this.getInputData();
const returnData = [];
for (let i = 0; i < items.length; i++) {
try {
const exchangeName = this.getNodeParameter('exchange', i);
const mode = this.getNodeParameter('mode', i);
const symbol = this.getNodeParameter('symbol', i);
const timeframe = this.getNodeParameter('timeframe', i);
const limit = this.getNodeParameter('limit', i, 50);
const since = this.getNodeParameter('since', i, '');
const options = this.getNodeParameter('options', i, {});
if (!symbol) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Symbol is required');
}
if (limit < 1 || limit > 1000) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Limit must be between 1 and 1000');
}
const exchangeConfig = {
sandbox: options.sandbox || false,
};
if (options.apiKey) {
exchangeConfig.apiKey = options.apiKey;
}
if (options.secret) {
exchangeConfig.secret = options.secret;
}
if (options.password) {
exchangeConfig.password = options.password;
}
const ExchangeClass = ccxt[exchangeName];
if (!ExchangeClass) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unsupported exchange: ${exchangeName}`);
}
const exchange = new ExchangeClass(exchangeConfig);
if (mode === 'future') {
exchange.options.defaultType = 'future';
}
await exchange.loadMarkets();
if (!exchange.markets[symbol]) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Symbol ${symbol} not found on ${exchangeName}`);
}
const params = {};
let sinceTimestamp;
if (since) {
sinceTimestamp = new Date(since).getTime();
}
const ohlcvData = await exchange.fetchOHLCV(symbol, timeframe, sinceTimestamp, limit, params);
const transformedData = ohlcvData.map((candle) => {
const [timestamp, open, high, low, close, volume] = candle;
return [open, high, low, close, volume, timestamp];
});
const outputData = {
exchange: exchangeName,
mode,
symbol,
timeframe,
limit,
count: transformedData.length,
data: transformedData,
};
outputData.metadata = {
exchangeId: exchange.id,
exchangeName: exchange.name,
fetchTimestamp: new Date().toISOString(),
since: sinceTimestamp ? new Date(sinceTimestamp).toISOString() : undefined,
};
if (options.includeTimestamp === false) {
outputData.data = transformedData.map((candle) => candle.slice(0, 5));
}
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.GetOhlcv = GetOhlcv;
//# sourceMappingURL=GetOhlcv.node.js.map