Upload files to "static"
init
This commit is contained in:
92
static/bb.js
Normal file
92
static/bb.js
Normal file
@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Indicator Definition Object for Bollinger Bands (BB).
|
||||
* This object is used by the indicator manager to create and control the indicator.
|
||||
*/
|
||||
const BB_INDICATOR = {
|
||||
name: 'BB',
|
||||
label: 'Bollinger Bands (3 Sets)',
|
||||
usesBaseData: true, // This indicator needs the raw 1m data for its own aggregation
|
||||
params: [
|
||||
{ name: 'timeframe', type: 'number', defaultValue: 1440, min: 1, label: 'Timeframe (min)' },
|
||||
],
|
||||
// Hardcoded internal parameters, no longer exposed to the user.
|
||||
internalParams: {
|
||||
bb1_len_upper: 16, bb1_std_upper: 1.9, bb1_len_lower: 17, bb1_std_lower: 1.5,
|
||||
bb2_len_upper: 18, bb2_std_upper: 2.7, bb2_len_lower: 18, bb2_std_lower: 1.6,
|
||||
bb3_len_upper: 16, bb3_std_upper: 2.6, bb3_len_lower: 16, bb3_std_lower: 1.8,
|
||||
},
|
||||
calculateFull: calculateFullBollingerBands,
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates all three sets of Bollinger Bands for the entire dataset.
|
||||
* @param {Array<Object>} data An array of candle objects with 'close' and 'time' properties.
|
||||
* @param {Object} params An object containing the indicator's parameters (only timeframe from UI).
|
||||
* @returns {Object} An object containing arrays of data points for each band.
|
||||
*/
|
||||
function calculateFullBollingerBands(data, params) {
|
||||
const { timeframe } = params;
|
||||
const internal = BB_INDICATOR.internalParams;
|
||||
|
||||
// First, aggregate the base data into the desired timeframe for the BB calculation.
|
||||
const aggregatedData = aggregateCandles(data, timeframe);
|
||||
if (aggregatedData.length === 0) {
|
||||
return { bb1_upper: [], bb1_lower: [], bb2_upper: [], bb2_lower: [], bb3_upper: [], bb3_lower: [] };
|
||||
}
|
||||
|
||||
// Calculate each set of bands using the aggregated data
|
||||
const bb1 = calculateBands(aggregatedData, internal.bb1_len_upper, internal.bb1_std_upper, internal.bb1_len_lower, internal.bb1_std_lower);
|
||||
const bb2 = calculateBands(aggregatedData, internal.bb2_len_upper, internal.bb2_std_upper, internal.bb2_len_lower, internal.bb2_std_lower);
|
||||
const bb3 = calculateBands(aggregatedData, internal.bb3_len_upper, internal.bb3_std_upper, internal.bb3_len_lower, internal.bb3_std_lower);
|
||||
|
||||
// Extend the last point of each band to the latest candle time
|
||||
const lastCandleTime = data[data.length - 1].time;
|
||||
const extendLine = (bandData) => {
|
||||
if (bandData.length > 0) {
|
||||
const lastPoint = bandData[bandData.length - 1];
|
||||
if (lastPoint.time < lastCandleTime) {
|
||||
bandData.push({ ...lastPoint, time: lastCandleTime });
|
||||
}
|
||||
}
|
||||
return bandData;
|
||||
};
|
||||
|
||||
return {
|
||||
bb1_upper: extendLine(bb1.upper), bb1_lower: extendLine(bb1.lower),
|
||||
bb2_upper: extendLine(bb2.upper), bb2_lower: extendLine(bb2.lower),
|
||||
bb3_upper: extendLine(bb3.upper), bb3_lower: extendLine(bb3.lower),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to calculate a single set of upper and lower Bollinger Bands.
|
||||
* @returns {{upper: Array<Object>, lower: Array<Object>}}
|
||||
*/
|
||||
function calculateBands(data, upperLength, upperStdDev, lowerLength, lowerStdDev) {
|
||||
const upperBand = [];
|
||||
const lowerBand = [];
|
||||
|
||||
// Calculate Upper Band
|
||||
for (let i = upperLength - 1; i < data.length; i++) {
|
||||
const slice = data.slice(i - upperLength + 1, i + 1);
|
||||
const sma = slice.reduce((sum, candle) => sum + candle.close, 0) / upperLength;
|
||||
const stdDev = Math.sqrt(slice.reduce((sum, candle) => sum + Math.pow(candle.close - sma, 2), 0) / upperLength);
|
||||
upperBand.push({
|
||||
time: slice[slice.length - 1].time,
|
||||
value: sma + (stdDev * upperStdDev)
|
||||
});
|
||||
}
|
||||
|
||||
// Calculate Lower Band
|
||||
for (let i = lowerLength - 1; i < data.length; i++) {
|
||||
const slice = data.slice(i - lowerLength + 1, i + 1);
|
||||
const sma = slice.reduce((sum, candle) => sum + candle.close, 0) / lowerLength;
|
||||
const stdDev = Math.sqrt(slice.reduce((sum, candle) => sum + Math.pow(candle.close - sma, 2), 0) / lowerLength);
|
||||
lowerBand.push({
|
||||
time: slice[slice.length - 1].time,
|
||||
value: sma - (stdDev * lowerStdDev)
|
||||
});
|
||||
}
|
||||
|
||||
return { upper: upperBand, lower: lowerBand };
|
||||
}
|
||||
Reference in New Issue
Block a user