- Split inline JS into separate ES module files (indicators/, strategies/, ui/, utils/) - Fix brain.py strategy registry to use MAStrategy directly instead of missing modules - Add auto-backfill for detected data gaps in collector monitoring loop - Fix chart resize on sidebar toggle - Fix chart scrollToTime -> setVisibleLogicalRange
38 lines
1.5 KiB
JavaScript
38 lines
1.5 KiB
JavaScript
import { BaseIndicator } from './base.js';
|
|
|
|
export class RSIIndicator extends BaseIndicator {
|
|
calculate(candles) {
|
|
const period = this.params.period || 14;
|
|
const results = new Array(candles.length).fill(null);
|
|
let gains = 0, losses = 0;
|
|
for (let i = 1; i < candles.length; i++) {
|
|
const diff = candles[i].close - candles[i-1].close;
|
|
const gain = diff > 0 ? diff : 0;
|
|
const loss = diff < 0 ? -diff : 0;
|
|
if (i <= period) {
|
|
gains += gain;
|
|
losses += loss;
|
|
if (i === period) {
|
|
let avgGain = gains / period;
|
|
let avgLoss = losses / period;
|
|
results[i] = 100 - (100 / (1 + (avgGain / (avgLoss || 0.00001))));
|
|
}
|
|
} else {
|
|
const lastAvgGain = (results[i-1] ? (results[i-1] > 0 ? (period-1) * (results[i-1] * (gains+losses)/100) : 0) : 0);
|
|
gains = (gains * (period - 1) + gain) / period;
|
|
losses = (losses * (period - 1) + loss) / period;
|
|
results[i] = 100 - (100 / (1 + (gains / (losses || 0.00001))));
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
getMetadata() {
|
|
return {
|
|
name: 'RSI',
|
|
inputs: [{ name: 'period', label: 'Period', type: 'number', default: 14, min: 1, max: 100 }],
|
|
plots: [{ id: 'value', color: '#9c27b0', title: 'RSI' }]
|
|
};
|
|
}
|
|
}
|