OnParamsChange
What is it?
The OnParamsChange
method is called automatically when the user changes any parameter of your indicator — for example, the period, color, MA type, etc.
It allows you to respond to these changes and implement custom logic that should happen when parameters are modified.
Important: This method is NOT used for the actual parameter values to change — that happens internally. This method is only for custom logic that needs to be executed when parameters are changed.
Syntax
public OnParamsChange(): void {
// custom logic after parameter change
}
When and Why to Use It
This method is called after the user updates the settings in the indicator panel, but before the indicator is recalculated.
Use OnParamsChange() When You Need To:
Recalculate internal values based on new parameter values
Adjust or re-create custom chart objects (lines, labels, etc.)
Update dependencies between parameters
Perform validation or parameter-based setup
Reset internal state that depends on parameters
Apply dynamic styling or configuration changes
Don't Use OnParamsChange() If:
You only need basic parameter changes (values update automatically)
You don't have any custom logic dependent on parameter changes
Your indicator works fine with just
Init()
andCalculate()
What CAN Be Done in OnParamsChange
OnParamsChange
Buffer and Display Updates
Modify buffer properties (styles, labels, visibility)
Update buffer configuration based on parameter changes
Reconfigure drawing styles and colors
Adjust buffer drawing ranges with
SetIndexDrawBegin()
Chart Object Management
Create, modify, or remove custom chart objects
Update object positions based on parameter changes
Reconfigure object properties (colors, styles, positions)
Manage dynamic visual elements
Internal State Management
Reset calculation counters or accumulators
Update lookup tables or cached calculations
Reconfigure internal algorithms based on parameters
Initialize parameter-dependent variables
What CANNOT Be Done in OnParamsChange
OnParamsChange
❌ Forbidden Operations
Heavy calculations or complex mathematical operations
Per-bar data processing (this should be in
Calculate()
)Modifying the actual parameter values (handled internally)
Creating new parameters (must be done in
Init()
)Changing buffer count with
IndicatorBuffers()
(must be inInit()
)Loops through large datasets or historical data processing
❌ Wrong Approach
public OnParamsChange(): void {
// DON'T DO THIS - heavy calculations
for (let i = 0; i < 1000; i++) {
let value = this.api.Close(i) * this.period.value; // ❌ Wrong!
this.mainBuffer.setValue(i, value); // ❌ Wrong!
}
// DON'T DO THIS - creating new parameters
this.newParam = this.api.createTOptValue_number(10); // ❌ Wrong!
this.api.RegOption("New Param", TOptionType.INTEGER, this.newParam); // ❌ Wrong!
}
✅ Correct Approach
public OnParamsChange(): void {
// ✅ Correct - lightweight parameter-dependent logic
this.internalMultiplier = this.period.value * 2;
// ✅ Correct - update buffer styling based on parameters
if (this.showLine.value) {
this.api.SetIndexStyle(0, TDrawStyle.LINE, TPenStyle.SOLID, 1, this.lineColor.value);
} else {
this.api.SetIndexVisibility(0, false);
}
// ✅ Correct - reset internal state
this.calculationCounter = 0;
}
Practical Examples
Example 1: Dynamic Buffer Styling
export default class CustomIndicator extends IndicatorImplementation {
public period!: TOptValue_number;
public lineColor!: TOptValue_str;
public showLine!: TOptValue_bool;
public mainBuffer!: TIndexBuffer;
public OnParamsChange(): void {
// Update line color when user changes it
this.api.SetIndexStyle(
0,
TDrawStyle.LINE,
TPenStyle.SOLID,
1,
this.lineColor.value
);
// Show/hide line based on boolean parameter
this.api.SetIndexVisibility(0, this.showLine.value);
// Adjust drawing start based on period
this.api.SetIndexDrawBegin(0, this.period.value);
}
}
Example 2: Parameter Validation and Dependencies
export default class AdvancedIndicator extends IndicatorImplementation {
public fastPeriod!: TOptValue_number;
public slowPeriod!: TOptValue_number;
public validConfiguration: boolean = true;
public OnParamsChange(): void {
// Validate parameter relationship
if (this.fastPeriod.value >= this.slowPeriod.value) {
this.validConfiguration = false;
// Could log warning or set visual indicator
} else {
this.validConfiguration = true;
}
// Update internal calculation variables
this.periodDifference = this.slowPeriod.value - this.fastPeriod.value;
}
private periodDifference: number = 0;
}
Example 3: Chart Object Management
export default class LevelIndicator extends IndicatorImplementation {
public levelValue!: TOptValue_number;
public showLevel!: TOptValue_bool;
public OnParamsChange(): void {
// Remove existing level line
this.api.RemoveAllObjects();
// Create new level line if enabled
if (this.showLevel.value) {
// Create horizontal line at new level value
this.CreateLevelLine(this.levelValue.value);
}
}
private CreateLevelLine(value: number): void {
// Custom method to create chart objects
// Implementation depends on your specific needs
}
}
Best Practices
✅ Do This
Keep it lightweight - only essential parameter-dependent logic
Use it for setup/configuration that depends on parameters
Reset internal state when parameters change
Update visual properties based on parameter values
Validate parameter combinations if needed
❌ Avoid This
Heavy computational work (belongs in
Calculate()
)Complex loops or data processing
Modifying parameter values
Creating new parameters or buffers (belongs in
Init()
)
When NOT to Implement OnParamsChange()
You can skip implementing this method if:
Your indicator only uses basic parameters for calculations
No custom logic is needed when parameters change
All parameter-dependent behavior happens in
Calculate()
You don't have dynamic visual elements or chart objects
Key Rules Summary
OnParamsChange() is optional - only implement if you need custom logic
Keep it lightweight - no heavy calculations or data processing
Parameter values update automatically - this method is for additional logic only
Use it for configuration and setup that depends on parameter values
Cannot create new parameters or buffers - only modify existing ones
Runs before recalculation - perfect for resetting internal state
Great for dynamic visuals - updating styles, objects, and display properties
Pro Tip
Think of OnParamsChange()
as your "parameter change reaction" method. It's the perfect place to update anything that depends on parameter values but doesn't belong in the per-bar Calculate()
method. Keep it fast and focused on configuration rather than calculation.
Last updated