- Build indicator list dynamically from class getMetadata() instead of hardcoded array - Remove checkboxes; single-click previews config, double-click adds to chart - Support multiple instances of same indicator type (unique IDs) - Add TradingView-style column legend overlay on chart (top-left) - Recalculate indicators when historical data is prefetched on scroll - Make indicator list and config panels scrollable (hidden scrollbars) - Remove AVAILABLE_INDICATORS from strategies/config.js
46 lines
1.6 KiB
JavaScript
46 lines
1.6 KiB
JavaScript
import { BaseIndicator } from './base.js';
|
|
|
|
export class StochasticIndicator extends BaseIndicator {
|
|
calculate(candles) {
|
|
const kPeriod = this.params.kPeriod || 14;
|
|
const dPeriod = this.params.dPeriod || 3;
|
|
const results = new Array(candles.length).fill(null);
|
|
|
|
const kValues = new Array(candles.length).fill(null);
|
|
|
|
for (let i = kPeriod - 1; i < candles.length; i++) {
|
|
let lowest = Infinity;
|
|
let highest = -Infinity;
|
|
for (let j = 0; j < kPeriod; j++) {
|
|
lowest = Math.min(lowest, candles[i-j].low);
|
|
highest = Math.max(highest, candles[i-j].high);
|
|
}
|
|
const diff = highest - lowest;
|
|
kValues[i] = diff === 0 ? 50 : ((candles[i].close - lowest) / diff) * 100;
|
|
}
|
|
|
|
for (let i = kPeriod + dPeriod - 2; i < candles.length; i++) {
|
|
let sum = 0;
|
|
for (let j = 0; j < dPeriod; j++) sum += kValues[i-j];
|
|
results[i] = { k: kValues[i], d: sum / dPeriod };
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
getMetadata() {
|
|
return {
|
|
name: 'Stochastic',
|
|
description: 'Stochastic Oscillator - compares close to high-low range',
|
|
inputs: [
|
|
{ name: 'kPeriod', label: 'K Period', type: 'number', default: 14 },
|
|
{ name: 'dPeriod', label: 'D Period', type: 'number', default: 3 }
|
|
],
|
|
plots: [
|
|
{ id: 'k', color: '#3f51b5', title: '%K' },
|
|
{ id: 'd', color: '#ff9800', title: '%D' }
|
|
]
|
|
};
|
|
}
|
|
}
|