Add BollingerBandsPercentBMomentumBreakout indicator support across application

- Introduced BollingerBandsPercentBMomentumBreakout indicator in GeneticService with configuration settings for period and multiplier.
- Updated ScenarioHelpers to handle creation and validation of the new indicator type.
- Enhanced CustomScenario, backtest, and scenario pages to include BollingerBandsPercentBMomentumBreakout in indicator lists and parameter mappings.
- Modified API and types to reflect the addition of the new indicator in relevant enums and mappings.
This commit is contained in:
2025-11-24 17:31:17 +07:00
parent 9f7e345457
commit 478dca51e7
11 changed files with 286 additions and 3 deletions

View File

@@ -47,6 +47,7 @@ const CustomScenario: React.FC<ICustomScenario> = ({
case IndicatorType.SuperTrend:
case IndicatorType.SuperTrendCrossEma:
case IndicatorType.ChandelierExit:
case IndicatorType.BollingerBandsPercentBMomentumBreakout:
params = ['period', 'multiplier'];
break;

View File

@@ -485,6 +485,47 @@ const TradeChart = ({
chandelierExitsShortsSeries.setData(chandelierExitsShorts)
}
// Display Bollinger Bands on price chart
if (indicatorsValues?.BollingerBandsPercentBMomentumBreakout != null) {
const upperBandSeries = chart.current.addLineSeries({
color: theme.error,
lineWidth: 1,
priceLineVisible: false,
priceLineWidth: 1,
title: 'Upper Band',
pane: 0,
lineStyle: LineStyle.Dashed,
})
const upperBandData = indicatorsValues.BollingerBandsPercentBMomentumBreakout.bollingerBands?.map((w) => {
return {
time: moment(w.date).unix(),
value: w.upperBand,
}
})
// @ts-ignore
upperBandSeries.setData(upperBandData)
const lowerBandSeries = chart.current.addLineSeries({
color: theme.success,
lineWidth: 1,
priceLineVisible: false,
priceLineWidth: 1,
title: 'Lower Band',
pane: 0,
lineStyle: LineStyle.Dashed,
})
const lowerBandData = indicatorsValues.BollingerBandsPercentBMomentumBreakout.bollingerBands?.map((w) => {
return {
time: moment(w.date).unix(),
value: w.lowerBand,
}
})
// @ts-ignore
lowerBandSeries.setData(lowerBandData)
}
if (markers.length > 0) {
series1.current.setMarkers(markers)
}
@@ -843,6 +884,37 @@ const TradeChart = ({
})
paneCount++
}
// Display Bollinger Bands %B
if (indicatorsValues?.BollingerBandsPercentBMomentumBreakout != null) {
const percentBSeries = chart.current.addLineSeries({
color: theme.primary,
lineWidth: 1,
priceLineVisible: false,
priceLineWidth: 1,
title: '%B',
pane: paneCount,
priceFormat: {
precision: 2,
type: 'price',
},
})
const percentBData = indicatorsValues.BollingerBandsPercentBMomentumBreakout.bollingerBands?.map((w) => {
return {
time: moment(w.date).unix(),
value: w.percentB,
}
})
// @ts-ignore
percentBSeries.setData(percentBData)
// Add reference lines for momentum thresholds
percentBSeries.createPriceLine(buildLine(theme.error, 0.8, 'Upper Threshold'))
percentBSeries.createPriceLine(buildLine(theme.success, 0.2, 'Lower Threshold'))
paneCount++
}
}
return (

View File

@@ -4984,6 +4984,7 @@ export enum IndicatorType {
LaggingStc = "LaggingStc",
SuperTrendCrossEma = "SuperTrendCrossEma",
DualEmaCross = "DualEmaCross",
BollingerBandsPercentBMomentumBreakout = "BollingerBandsPercentBMomentumBreakout",
}
export enum SignalType {

View File

@@ -450,6 +450,7 @@ export enum IndicatorType {
LaggingStc = "LaggingStc",
SuperTrendCrossEma = "SuperTrendCrossEma",
DualEmaCross = "DualEmaCross",
BollingerBandsPercentBMomentumBreakout = "BollingerBandsPercentBMomentumBreakout",
}
export enum SignalType {

View File

@@ -104,6 +104,7 @@ const ALL_INDICATORS = [
IndicatorType.SuperTrendCrossEma,
IndicatorType.DualEmaCross,
IndicatorType.StochasticCross,
IndicatorType.BollingerBandsPercentBMomentumBreakout,
]
// Indicator type to parameter mapping
@@ -119,6 +120,7 @@ const INDICATOR_PARAM_MAPPING = {
[IndicatorType.SuperTrend]: ['period', 'multiplier'],
[IndicatorType.SuperTrendCrossEma]: ['period', 'multiplier'],
[IndicatorType.ChandelierExit]: ['period', 'multiplier'],
[IndicatorType.BollingerBandsPercentBMomentumBreakout]: ['period', 'multiplier'],
[IndicatorType.StochRsiTrend]: ['period', 'stochPeriods', 'signalPeriods', 'smoothPeriods'],
[IndicatorType.StochasticCross]: ['stochPeriods', 'signalPeriods', 'smoothPeriods', 'kFactor', 'dFactor'],
[IndicatorType.Stc]: ['cyclePeriods', 'fastPeriods', 'slowPeriods'],

View File

@@ -43,6 +43,7 @@ const ALL_INDICATORS = [
IndicatorType.SuperTrendCrossEma,
IndicatorType.DualEmaCross,
IndicatorType.StochasticCross,
IndicatorType.BollingerBandsPercentBMomentumBreakout,
]
// Form Interface

View File

@@ -314,7 +314,8 @@ const IndicatorList: React.FC = () => {
{indicatorType == IndicatorType.SuperTrend ||
indicatorType == IndicatorType.SuperTrendCrossEma ||
indicatorType == IndicatorType.ChandelierExit ? (
indicatorType == IndicatorType.ChandelierExit ||
indicatorType == IndicatorType.BollingerBandsPercentBMomentumBreakout ? (
<>
<div className="form-control">
<div className="input-group">