Files
btc-trading/scratch.js

92 lines
3.8 KiB
JavaScript

import { BaseIndicator } from './base.js';
export class RSIIndicator extends BaseIndicator {
calculate(candles) {
const period = this.params.period || 14;
// 1. Calculate RSI using RMA (Wilder's Smoothing)
let rsiValues = new Array(candles.length).fill(null);
let upSum = 0;
let downSum = 0;
const rmaAlpha = 1 / period;
for (let i = 1; i < candles.length; i++) {
const diff = candles[i].close - candles[i-1].close;
const up = diff > 0 ? diff : 0;
const down = diff < 0 ? -diff : 0;
if (i < period) {
upSum += up;
downSum += down;
} else if (i === period) {
upSum += up;
downSum += down;
const avgUp = upSum / period;
const avgDown = downSum / period;
rsiValues[i] = avgDown === 0 ? 100 : (avgUp === 0 ? 0 : 100 - (100 / (1 + avgUp / avgDown)));
upSum = avgUp; // Store for next RMA step
downSum = avgDown;
} else {
upSum = (up - upSum) * rmaAlpha + upSum;
downSum = (down - downSum) * rmaAlpha + downSum;
rsiValues[i] = downSum === 0 ? 100 : (upSum === 0 ? 0 : 100 - (100 / (1 + upSum / downSum)));
}
}
// Combine results
return rsiValues.map((rsi, i) => {
return {
paneBg: 100, // Background lightening trick
rsi: rsi,
upperBand: 70,
lowerBand: 30
};
});
}
getMetadata() {
const plots = [
// Background lightness trick (spans from 0 to 100 constantly)
// Making it darker by reducing opacity since the main background is dark.
{ id: 'paneBg', type: 'baseline', baseValue: 0, color: 'transparent',
topLineColor: 'transparent', bottomLineColor: 'transparent',
topFillColor1: 'rgba(255, 255, 255, 0.015)', topFillColor2: 'rgba(255, 255, 255, 0.015)',
bottomFillColor1: 'transparent', bottomFillColor2: 'transparent',
title: '', lastValueVisible: false, width: 0 },
// Overbought Gradient Fill (> 70)
{ id: 'rsi', type: 'baseline', baseValue: 70, color: 'transparent',
topLineColor: 'transparent', bottomLineColor: 'transparent',
topFillColor1: 'rgba(244, 67, 54, 0.8)', topFillColor2: 'rgba(244, 67, 54, 0.2)',
bottomFillColor1: 'transparent', bottomFillColor2: 'transparent',
title: '', lastValueVisible: false, width: 0 },
// Oversold Gradient Fill (< 30)
{ id: 'rsi', type: 'baseline', baseValue: 30, color: 'transparent',
topLineColor: 'transparent', bottomLineColor: 'transparent',
topFillColor1: 'transparent', topFillColor2: 'transparent',
bottomFillColor1: 'rgba(76, 175, 80, 0.2)', bottomFillColor2: 'rgba(76, 175, 80, 0.8)',
title: '', lastValueVisible: false, width: 0 },
// RSI Line
{ id: 'rsi', color: '#7E57C2', title: '', width: 1, lastValueVisible: true },
// Bands
{ id: 'upperBand', color: '#787B86', title: '', style: 'dashed', width: 1, lastValueVisible: false },
{ id: 'lowerBand', color: '#787B86', title: '', style: 'dashed', width: 1, lastValueVisible: false }
];
return {
name: 'RSI',
description: 'Relative Strength Index',
inputs: [
{ name: 'period', label: 'RSI Length', type: 'number', default: 14, min: 1, max: 100 }
],
plots: plots,
displayMode: 'pane',
paneMin: 0,
paneMax: 100
};
}
}