dual hurst + removed labels
This commit is contained in:
@ -7,18 +7,17 @@
|
||||
*/
|
||||
function createIndicatorManager(chart, baseCandleDataRef, displayedCandleDataRef) {
|
||||
const indicatorSlots = [
|
||||
{ id: 1, cellId: 'indicator-cell-1', series: [], definition: null, params: {} },
|
||||
{ id: 2, cellId: 'indicator-cell-2', series: [], definition: null, params: {} },
|
||||
{ id: 3, cellId: 'indicator-cell-3', series: [], definition: null, params: {} },
|
||||
{ id: 4, cellId: 'indicator-cell-4', series: [], definition: null, params: {} },
|
||||
{ id: 1, cellId: 'indicator-cell-1', series: [], definition: null, params: {}, calculator: null },
|
||||
{ id: 2, cellId: 'indicator-cell-2', series: [], definition: null, params: {}, calculator: null },
|
||||
{ id: 3, cellId: 'indicator-cell-3', series: [], definition: null, params: {}, calculator: null },
|
||||
{ id: 4, cellId: 'indicator-cell-4', series: [], definition: null, params: {}, calculator: null },
|
||||
];
|
||||
|
||||
// **FIX**: Updated colors object to match your styling request.
|
||||
const colors = {
|
||||
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']
|
||||
bb: { bb1_upper: '#FF9800', bb1_lower: '#FF9800', bb2_upper: '#2196F3', bb2_lower: '#2196F3', bb3_upper: '#9C27B0', bb3_lower: '#9C27B0' },
|
||||
hurst: { topBand: '#787b86', bottomBand: '#787b86', topBand_h: '#673ab7', bottomBand_h: '#673ab7' },
|
||||
default: ['#00BCD4', '#FFEB3B', '#4CAF50', '#E91E63'] // Cyan, Yellow, Green, Pink
|
||||
};
|
||||
|
||||
function populateDropdowns() {
|
||||
@ -51,6 +50,7 @@ function createIndicatorManager(chart, baseCandleDataRef, displayedCandleDataRef
|
||||
slot.series = [];
|
||||
slot.definition = null;
|
||||
slot.params = {};
|
||||
slot.calculator = null;
|
||||
|
||||
const controlsContainer = document.querySelector(`#${slot.cellId} .indicator-controls`);
|
||||
controlsContainer.innerHTML = '';
|
||||
@ -80,7 +80,7 @@ function createIndicatorManager(chart, baseCandleDataRef, displayedCandleDataRef
|
||||
clearTimeout(debounceTimer);
|
||||
debounceTimer = setTimeout(() => {
|
||||
slot.params[param.name] = input.type === 'number' ? parseFloat(input.value) : input.value;
|
||||
updateIndicator(slot.id);
|
||||
updateIndicator(slot.id, true);
|
||||
}, 500);
|
||||
});
|
||||
const controlGroup = document.createElement('div');
|
||||
@ -91,45 +91,69 @@ function createIndicatorManager(chart, baseCandleDataRef, displayedCandleDataRef
|
||||
controlsContainer.appendChild(controlGroup);
|
||||
});
|
||||
|
||||
updateIndicator(slot.id);
|
||||
updateIndicator(slot.id, true);
|
||||
}
|
||||
|
||||
function updateIndicator(slotId) {
|
||||
function updateIndicator(slotId, isFullRecalculation = false) {
|
||||
const slot = indicatorSlots.find(s => s.id === slotId);
|
||||
const candleDataForCalc = (slot.definition.usesBaseData) ? baseCandleDataRef : displayedCandleDataRef;
|
||||
|
||||
if (!slot || !slot.definition || candleDataForCalc.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (!slot || !slot.definition || candleDataForCalc.length === 0) return;
|
||||
|
||||
slot.series.forEach(s => chart.removeSeries(s));
|
||||
slot.series = [];
|
||||
|
||||
const indicatorResult = slot.definition.calculateFull(candleDataForCalc, slot.params);
|
||||
|
||||
if (typeof indicatorResult === 'object' && !Array.isArray(indicatorResult)) {
|
||||
Object.keys(indicatorResult).forEach(key => {
|
||||
const seriesData = indicatorResult[key];
|
||||
const indicatorNameLower = slot.definition.name.toLowerCase();
|
||||
|
||||
const series = chart.addLineSeries({
|
||||
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,
|
||||
if (isFullRecalculation) {
|
||||
slot.series.forEach(s => chart.removeSeries(s));
|
||||
slot.series = [];
|
||||
|
||||
const indicatorResult = slot.definition.calculateFull(candleDataForCalc, slot.params);
|
||||
|
||||
if (typeof indicatorResult === 'object' && !Array.isArray(indicatorResult)) {
|
||||
Object.keys(indicatorResult).forEach(key => {
|
||||
const seriesData = indicatorResult[key];
|
||||
const indicatorNameLower = slot.definition.name.toLowerCase();
|
||||
const series = chart.addLineSeries({
|
||||
color: (colors[indicatorNameLower] && colors[indicatorNameLower][key]) ? colors[indicatorNameLower][key] : colors.default[slot.id - 1],
|
||||
lineWidth: 1, // **FIX**: Set line width to 1px
|
||||
title: '', // **FIX**: Remove title label
|
||||
lastValueVisible: false, // **FIX**: Remove price label on the right
|
||||
priceLineVisible: false, // **FIX**: Remove dotted horizontal line
|
||||
});
|
||||
series.setData(seriesData);
|
||||
slot.series.push(series);
|
||||
});
|
||||
series.setData(seriesData);
|
||||
} else {
|
||||
const series = chart.addLineSeries({
|
||||
color: colors.default[slot.id - 1],
|
||||
lineWidth: 1, // **FIX**: Set line width to 1px
|
||||
title: '', // **FIX**: Remove title label
|
||||
lastValueVisible: false, // **FIX**: Remove price label on the right
|
||||
priceLineVisible: false, // **FIX**: Remove dotted horizontal line
|
||||
});
|
||||
series.setData(indicatorResult);
|
||||
slot.series.push(series);
|
||||
});
|
||||
} else {
|
||||
const series = chart.addLineSeries({
|
||||
color: colors.default[slot.id - 1],
|
||||
lineWidth: 2,
|
||||
title: slot.definition.label,
|
||||
});
|
||||
series.setData(indicatorResult);
|
||||
slot.series.push(series);
|
||||
}
|
||||
|
||||
if (slot.definition.createRealtime) {
|
||||
slot.calculator = slot.definition.createRealtime(slot.params);
|
||||
slot.calculator.prime(candleDataForCalc);
|
||||
}
|
||||
} else if (slot.calculator) {
|
||||
// **FIX**: This is the lightweight real-time update logic
|
||||
const lastCandle = candleDataForCalc[candleDataForCalc.length - 1];
|
||||
if (!lastCandle) return;
|
||||
|
||||
const newPoint = slot.calculator.update(lastCandle);
|
||||
|
||||
if (newPoint && typeof newPoint === 'object') {
|
||||
if (slot.series.length > 1) { // Multi-line indicator
|
||||
Object.keys(newPoint).forEach((key, index) => {
|
||||
if (slot.series[index] && newPoint[key]) {
|
||||
slot.series[index].update(newPoint[key]);
|
||||
}
|
||||
});
|
||||
} else if (slot.series.length === 1) { // Single-line indicator
|
||||
slot.series[0].update(newPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,12 +161,22 @@ function createIndicatorManager(chart, baseCandleDataRef, displayedCandleDataRef
|
||||
baseCandleDataRef = baseData;
|
||||
displayedCandleDataRef = displayedData;
|
||||
indicatorSlots.forEach(slot => {
|
||||
if (slot.definition) updateIndicator(slot.id);
|
||||
if (slot.definition) updateIndicator(slot.id, true);
|
||||
});
|
||||
}
|
||||
|
||||
// **FIX**: New lightweight function for real-time updates
|
||||
function updateAllOnNewCandle() {
|
||||
indicatorSlots.forEach(slot => {
|
||||
if (slot.definition) {
|
||||
updateIndicator(slot.id, false); // Perform a lightweight update
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
populateDropdowns,
|
||||
recalculateAllAfterHistory,
|
||||
updateAllOnNewCandle, // Expose the new function
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user