first hurst working, only for current TF
This commit is contained in:
@ -2,13 +2,10 @@
|
||||
* Creates and manages all indicator-related logic for the chart.
|
||||
* @param {Object} chart - The Lightweight Charts instance.
|
||||
* @param {Array<Object>} baseCandleData - A reference to the array holding the chart's BASE 1m candle data.
|
||||
* @param {Array<Object>} displayedCandleData - A reference to the array with currently visible candles.
|
||||
* @returns {Object} A manager object with public methods to control indicators.
|
||||
*/
|
||||
function createIndicatorManager(chart, baseCandleData) {
|
||||
// This holds the candle data currently displayed on the chart (e.g., 5m, 10m)
|
||||
let currentAggregatedData = [];
|
||||
|
||||
// Defines the 4 slots available in the UI for indicators.
|
||||
function createIndicatorManager(chart, baseCandleData, displayedCandleData) {
|
||||
const indicatorSlots = [
|
||||
{ id: 1, cellId: 'indicator-cell-1', series: [], definition: null, params: {} },
|
||||
{ id: 2, cellId: 'indicator-cell-2', series: [], definition: null, params: {} },
|
||||
@ -16,17 +13,14 @@ function createIndicatorManager(chart, baseCandleData) {
|
||||
{ id: 4, cellId: 'indicator-cell-4', series: [], definition: null, params: {} },
|
||||
];
|
||||
|
||||
// Pre-defined colors for the indicator lines.
|
||||
const colors = {
|
||||
bb1: { upper: '#FF9800', lower: '#FF9800' }, // Orange
|
||||
bb2: { upper: '#2196F3', lower: '#2196F3' }, // Blue
|
||||
bb3: { upper: '#9C27B0', lower: '#9C27B0' }, // Purple
|
||||
default: ['#FF5722', '#03A9F4', '#8BC34A', '#F44336'] // Fallback colors for other indicators
|
||||
bb1: { upper: '#FF9800', lower: '#FF9800' },
|
||||
bb2: { upper: '#2196F3', lower: '#2196F3' },
|
||||
bb3: { upper: '#9C27B0', lower: '#9C27B0' },
|
||||
hurst: { topBand: '#673ab7', bottomBand: '#673ab7' },
|
||||
default: ['#FF5722', '#03A9F4', '#8BC34A', '#F44336']
|
||||
};
|
||||
|
||||
/**
|
||||
* Populates the dropdown menus in each indicator cell.
|
||||
*/
|
||||
function populateDropdowns() {
|
||||
indicatorSlots.forEach(slot => {
|
||||
const cell = document.getElementById(slot.cellId);
|
||||
@ -41,30 +35,20 @@ function createIndicatorManager(chart, baseCandleData) {
|
||||
const controlsContainer = document.createElement('div');
|
||||
controlsContainer.className = 'indicator-controls';
|
||||
|
||||
cell.innerHTML = ''; // Clear previous content
|
||||
cell.innerHTML = '';
|
||||
cell.appendChild(select);
|
||||
cell.appendChild(controlsContainer);
|
||||
|
||||
select.addEventListener('change', (e) => {
|
||||
const indicatorName = e.target.value;
|
||||
loadIndicator(slot.id, indicatorName);
|
||||
});
|
||||
select.addEventListener('change', (e) => loadIndicator(slot.id, e.target.value));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a new indicator into a specified slot.
|
||||
* @param {number} slotId - The ID of the slot (1-4).
|
||||
* @param {string} indicatorName - The name of the indicator to load (e.g., 'SMA').
|
||||
*/
|
||||
function loadIndicator(slotId, indicatorName) {
|
||||
const slot = indicatorSlots.find(s => s.id === slotId);
|
||||
if (!slot) return;
|
||||
|
||||
// Clean up any previous indicator series in this slot
|
||||
slot.series.forEach(s => chart.removeSeries(s));
|
||||
slot.series = [];
|
||||
|
||||
slot.definition = null;
|
||||
slot.params = {};
|
||||
|
||||
@ -78,7 +62,6 @@ function createIndicatorManager(chart, baseCandleData) {
|
||||
|
||||
slot.definition = definition;
|
||||
|
||||
// Create UI controls for the indicator's parameters
|
||||
definition.params.forEach(param => {
|
||||
const label = document.createElement('label');
|
||||
label.textContent = param.label || param.name;
|
||||
@ -90,7 +73,6 @@ function createIndicatorManager(chart, baseCandleData) {
|
||||
if (param.min !== undefined) input.min = param.min;
|
||||
if (param.step !== undefined) input.step = param.step;
|
||||
input.className = 'input-field';
|
||||
input.placeholder = param.name;
|
||||
slot.params[param.name] = input.type === 'number' ? parseFloat(input.value) : input.value;
|
||||
|
||||
let debounceTimer;
|
||||
@ -112,37 +94,25 @@ function createIndicatorManager(chart, baseCandleData) {
|
||||
updateIndicator(slot.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculates and redraws the lines for a specific indicator.
|
||||
* @param {number} slotId - The ID of the slot to update.
|
||||
*/
|
||||
function updateIndicator(slotId) {
|
||||
const slot = indicatorSlots.find(s => s.id === slotId);
|
||||
|
||||
const candleDataForCalc = (slot.definition.usesBaseData) ? baseCandleData : currentAggregatedData;
|
||||
const candleDataForCalc = (slot.definition.usesBaseData) ? baseCandleData : displayedCandleData;
|
||||
|
||||
if (!slot || !slot.definition || candleDataForCalc.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (!slot || !slot.definition || candleDataForCalc.length === 0) return;
|
||||
|
||||
// Clean up previous series before creating new ones
|
||||
slot.series.forEach(s => chart.removeSeries(s));
|
||||
slot.series = [];
|
||||
|
||||
console.log(`Recalculating ${slot.definition.name} for slot ${slot.id} on ${candleDataForCalc.length} candles.`);
|
||||
|
||||
const indicatorResult = slot.definition.calculateFull(candleDataForCalc, slot.params);
|
||||
|
||||
// Handle multi-line indicators like Bollinger Bands
|
||||
if (typeof indicatorResult === 'object' && !Array.isArray(indicatorResult)) {
|
||||
Object.keys(indicatorResult).forEach(key => {
|
||||
const seriesData = indicatorResult[key];
|
||||
const bandName = key.split('_')[0];
|
||||
const bandType = key.split('_')[1];
|
||||
const indicatorNameLower = slot.definition.name.toLowerCase();
|
||||
|
||||
const series = chart.addLineSeries({
|
||||
color: colors[bandName] ? colors[bandName][bandType] : colors.default[slot.id - 1],
|
||||
lineWidth: 2,
|
||||
color: (colors[indicatorNameLower] && colors[indicatorNameLower][key]) ? colors[indicatorNameLower][key] : colors.default[slot.id - 1],
|
||||
lineWidth: indicatorNameLower === 'hurst' ? 1 : 2,
|
||||
title: `${slot.definition.label} - ${key}`,
|
||||
lastValueVisible: false,
|
||||
priceLineVisible: false,
|
||||
@ -150,7 +120,7 @@ function createIndicatorManager(chart, baseCandleData) {
|
||||
series.setData(seriesData);
|
||||
slot.series.push(series);
|
||||
});
|
||||
} else { // Handle single-line indicators like SMA/EMA
|
||||
} else {
|
||||
const series = chart.addLineSeries({
|
||||
color: colors.default[slot.id - 1],
|
||||
lineWidth: 2,
|
||||
@ -161,36 +131,18 @@ function createIndicatorManager(chart, baseCandleData) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function to recalculate all active indicators.
|
||||
*/
|
||||
function recalculateAllIndicators() {
|
||||
function recalculateAllAfterHistory(newDisplayedCandleData) {
|
||||
displayedCandleData = newDisplayedCandleData;
|
||||
indicatorSlots.forEach(slot => {
|
||||
if (slot.definition) {
|
||||
updateIndicator(slot.id);
|
||||
}
|
||||
if (slot.definition) updateIndicator(slot.id);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the candle data for indicators and triggers a full recalculation.
|
||||
* @param {Array<Object>} aggregatedCandleData - The candle data for the currently selected timeframe.
|
||||
*/
|
||||
function recalculateAllAfterHistory(aggregatedCandleData) {
|
||||
currentAggregatedData = aggregatedCandleData;
|
||||
recalculateAllIndicators();
|
||||
|
||||
// This function is not currently used with the new model but is kept for potential future use.
|
||||
function updateIndicatorsOnNewCandle(newCandle) {
|
||||
// Real-time updates would go here.
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates all indicators in response to a new candle closing.
|
||||
* @param {Array<Object>} aggregatedCandleData - The latest candle data for the currently selected timeframe.
|
||||
*/
|
||||
function updateIndicatorsOnNewCandle(aggregatedCandleData) {
|
||||
currentAggregatedData = aggregatedCandleData;
|
||||
recalculateAllIndicators();
|
||||
}
|
||||
|
||||
// Public API for the manager
|
||||
return {
|
||||
populateDropdowns,
|
||||
recalculateAllAfterHistory,
|
||||
|
||||
Reference in New Issue
Block a user