// ============================================================ // ANALYZE BTC TREND — EMA9/21/50 + RSI14 + ROC5 // ============================================================ function ema(closes, period) { if (closes.length < period) return closes[closes.length - 1] || 0; const k = 2 / (period + 1); let val = closes.slice(0, period).reduce((s, v) => s + v, 0) / period; for (let i = period; i < closes.length; i++) val = closes[i] * k + val * (1 - k); return val; } function rsiCalc(closes, period) { if (closes.length < period + 1) return 50; const slice = closes.slice(-(period + 1)); let g = 0, l = 0; for (let i = 1; i < slice.length; i++) { const d = slice[i] - slice[i - 1]; d >= 0 ? (g += d) : (l -= d); } const ag = g / period, al = l / period; return al === 0 ? 100 : 100 - 100 / (1 + ag / al); } const allBtcItems = $input.all(); let klines; if (allBtcItems.length > 1) { klines = allBtcItems.map(item => { const v = item.json; return Array.isArray(v) ? v : Object.values(v); }); } else { const rawInput = allBtcItems[0].json; if (Array.isArray(rawInput) && Array.isArray(rawInput[0])) { klines = rawInput; } else if (Array.isArray(rawInput)) { klines = rawInput.length > 0 && !Array.isArray(rawInput[0]) ? [rawInput] : rawInput; } else { klines = []; } } if (klines.length < 22) { return [{ json: { btcSignal: { trend: 'neutral', score: 0, ema9: 0, ema21: 0, ema50: 0, rsi: 50, roc5: 0, dataOk: false } } }]; } const closes = klines.map(k => parseFloat(k[4])); const n = closes.length; const price = closes[n - 1]; const EMA9 = ema(closes, 9); const EMA21 = ema(closes, 21); const EMA50 = ema(closes, Math.min(50, closes.length)); const RSI = rsiCalc(closes, 14); const roc5 = closes[n - 6] > 0 ? +((price - closes[n - 6]) / closes[n - 6] * 100).toFixed(4) : 0; let score = 0; if (EMA9 > EMA21) score += 0.5; else if (EMA9 < EMA21) score -= 0.5; if (price > EMA50) score += 0.5; else if (price < EMA50) score -= 0.5; if (RSI >= 55) score += 0.5; else if (RSI <= 45) score -= 0.5; if (roc5 >= 0.3) score += 0.5; else if (roc5 <= -0.3) score -= 0.5; score = +score.toFixed(2); const trend = score >= 1.0 ? 'bull' : score <= -1.0 ? 'bear' : 'neutral'; return [{ json: { btcSignal: { trend, score, ema9: +EMA9.toFixed(2), ema21: +EMA21.toFixed(2), ema50: +EMA50.toFixed(2), rsi: +RSI.toFixed(1), roc5, price: +price.toFixed(2), dataOk: true } } }];