Altering Study Settings
Every study's settings, such as an RSI's period and levels or a moving average's colour, can be changed while it is on the chart. This page covers altering study and indicator settings from code, through the study's descriptor. Built-in studies apply new settings in place: no data reloads, and the chart doesn't flash.
To let users edit settings themselves, use the ready-made Study Settings Form and Study List UI components, which edit the same descriptor.
Study Settings Are a Descriptor
A study describes its settings as a descriptor (TStudyDescriptor), in two sections:
inputs: what it calculates from, such as periods and levels;styles: how it looks, such as colours, line thickness and line style.
Each section is a set of named controls. A control has a type (number, colour, select…), a label for the settings form, and its current value in default:
const rsi = new RSIStudy({ length: 14 });
// ... once the RSI is on a chart:
const descriptor = rsi.getDescriptor(); // the RSI's current settings
descriptor.inputs.controls.period;
// { name: "period", type: "number", label: "Period", default: 14 }
descriptor.styles.controls.strokeColor;
// { name: "strokeColor", type: "color", label: "Stroke Color", default: "#…" }
Every study has these settings members. They are part of the IStudy interface, where their TSDoc is:
| Member | What it does |
|---|---|
study. | The study's current settings, read fresh from the live study |
study. | Applies settings to the live study |
study. | The settings the study had when first attached, for "reset to defaults" |
study. | Whether apply updates the study in place. true for every built-in study |
study. | Fires after apply, with the settings applied |
getDescriptor() refills and returns the same object on every call. Copy it before you keep it, e.g. as React state, or a later read changes your copy too.
Change settings with applyDescriptor, not setDescriptor. setDescriptor only stores a descriptor, without applying it to the chart, and the next getDescriptor() replaces it with the study's live settings. setDescriptor and addDescriptor are for writing a study.
The descriptor is also what Save and Restore saves for each study, so edited settings are kept.
The TStudyDescriptor type, IuiDescriptor interface, and EDescriptorSectionName and EDescriptorType enums, with their TSDoc
interface IuiDescriptor {
id?: string;
name: string;
type: string;
label: string;
default: string | number;
options?: {
value: string;
label: string;
}[];
}
interface IDescriptorControls {
[key: string]: IuiDescriptor;
}
type TStudyDescriptor = {
[Key in EDescriptorSectionName]: {
controls: IDescriptorControls;
};
enum EDescriptorSectionName {
STYLES = "styles",
INPUTS = "inputs"
}
enum EDescriptorType {
TEXT = "text",
NUMBER = "number",
SELECT = "select",
COLOR = "color",
STROKE_TYPE = "stroke-type",
/** A colour ramp: stops of colour and position, edited on a gradient bar. See {@link GradientDescriptor}. */
GRADIENT = "gradient"
}
Changing a Setting from Code with applyDescriptor
To change one setting, copy the study's descriptor with that one control's value changed, and apply the copy. A small helper does it for any study and setting:
import { EDescriptorSectionName, IStudy } from "scichart-scitrader";
// Set one control of a live study's settings, e.g. the RSI's "period"
function setStudySetting(study: IStudy, section: EDescriptorSectionName, control: string, value: string | number) {
const descriptor = study.getDescriptor(); // the current settings
const controls = descriptor[section].controls;
study.applyDescriptor({
...descriptor, // keep the other section as it is
[section]: {
// keep the section's other controls, and replace this control's value
controls: { ...controls, [control]: { ...controls[control], default: value } },
},
});
}
setStudySetting(rsi, EDescriptorSectionName.INPUTS, "period", 7); // an input: the RSI is recalculated
setStudySetting(rsi, EDescriptorSectionName.STYLES, "strokeColor", "#ff9f1c"); // a style: its line is recoloured
There is no one-call setter yet: changing one setting means copying the whole descriptor, and control names are strings. A simpler, typed API is logged as SCT-924.
A colour edit applies to the chart's current theme only, and the study keeps the colours it was given under other themes; see Styling and Themes.
Resetting a Study to Its Defaults with getDefaultDescriptor
getDefaultDescriptor() returns the settings the study had when it was first attached. Apply it to reset the study:
// Reset one study
rsi.applyDescriptor(rsi.getDefaultDescriptor());
// Reset every study on the chart
for (const study of financeChartPanel.financeApi.studies) {
study.applyDescriptor(study.getDefaultDescriptor());
}
Following Settings Changes with descriptorApplied
descriptorApplied fires after every applyDescriptor, whether from your code, a settings form or a reset. Use it to keep your own UI in step:
// Called with the settings just applied
rsi.descriptorApplied.subscribe((descriptor) => {
console.log("RSI period is now", descriptor.inputs.controls.period.default);
});
Settings Names of the Built-in Studies
Each study names its own controls. To see a study's, log study.getDescriptor(). For the built-in studies:
| Study | Inputs | Styles |
|---|---|---|
ADXStudy | period | adx, pdi, mdi, stroke |
ATRStudy | period | stroke, stroke, stroke |
Awesome | (none) | up, down |
Bollinger | period, std | upper, lower, middle, band, stroke |
CCIStudy | period | stroke, stroke, stroke |
Donchian | period | upper, lower, channel, basis, stroke |
EMAStudy | period | stroke, stroke, stroke |
Force | period | stroke, stroke, stroke |
Ichimoku | conversion, base, span, displacement | tenkan, kijun, senkou, senkou, chikou, cloud, cloud, stroke |
Keltner | ma, atr, multiplier | upper, lower, channel, basis, stroke |
Large | threshold | buy, sell, stroke |
Line | (none) | stroke, stroke, stroke |
MACDStudy | fast, slow, signal | histogram, histogram, band, band, fill, fill, stroke |
MFIStudy | period | stroke, stroke, stroke |
OBVStudy | (none) | stroke, stroke, stroke |
OHLCStudy | candle | brush, brush, stroke, stroke, data |
Order | side | palette, scale, color, color, opacity, min, ramp |
Order | method, pct | bid, ask, fill, fill, stroke, gauge |
Point | box, reversal | (none) |
PSARStudy | step, max | dot, dot |
Renko | brick, reversal | (none) |
ROCStudy | period | stroke, stroke, stroke |
RSIStudy | period, overbought, oversold | stroke, stroke, stroke, threshold, overbought, oversold |
SMAStudy | period | stroke, stroke, stroke |
Stochastic | period, signal | stroke, stroke, stroke |
TRIXStudy | period | stroke, stroke, stroke |
Volume | (none) | volume, volume, data |
Volume | bin, range | fill, width, data, side, show, point |
VWAPStudy | (none) | stroke, stroke, stroke |
Williams | period | stroke, stroke, stroke |
WMAStudy | period | stroke, stroke, stroke |
strokeStyle is "solid", "dashed" or "dotted".
TypeScript Example: Changing Study Settings from Code
A BTC-USD chart from Coinbase with Volume, SMA and RSI. The buttons change the RSI's settings in code: its period (an input, so the RSI is recalculated) and its line colour (a style). Reset RSI applies getDefaultDescriptor(). The panel on the right shows the RSI's descriptor, refreshed on descriptorApplied, so you can watch the values change.
The code for this example is found below.
- TS
import "scichart-scitrader/scitrader.css";
import {
CandleInterval,
CoinbaseExchange,
defaultExchangeProvider,
EDescriptorSectionName,
idbPriceStore,
IStudy,
OHLCStudy,
RSIStudy,
SciFinanceChartPanel,
SMAStudy,
VolumeStudy,
} from "scichart-scitrader";
// This example expects this HTML:
// <div style="display: flex; flex-direction: column; height: 100%">
// <div id="toolbar"></div>
// <div style="display: flex; flex: 1; min-height: 0">
// <div id="chart" style="flex: 1; min-width: 0"></div>
// <pre id="descriptor" style="width: 320px; margin: 0; overflow: auto"></pre>
// </div>
// </div>
// Register a data source, once, at app startup
defaultExchangeProvider.registerExchange(CoinbaseExchange, idbPriceStore);
// Change one setting of a live study, in code.
// A study's settings are its descriptor: an "inputs" section (periods, levels) and a "styles"
// section (colours, thickness), each a set of named controls holding their value in `default`.
// Copy the descriptor with one value changed and apply it: built-in studies update in place
function setStudySetting(study: IStudy, section: EDescriptorSectionName, control: string, value: string | number) {
const descriptor = study.getDescriptor();
const controls = descriptor[section].controls;
study.applyDescriptor({
...descriptor,
[section]: { controls: { ...controls, [control]: { ...controls[control], default: value } } },
});
}
async function createChart() {
const toolbar = document.getElementById("toolbar");
Object.assign(toolbar.style, toolbarStyle);
const descriptorView = document.getElementById("descriptor");
Object.assign(descriptorView.style, descriptorStyle);
const rsi = new RSIStudy({ length: 14 });
const financeChartPanel = await SciFinanceChartPanel.create(document.getElementById("chart"), {
exchangeName: CoinbaseExchange.name, // name="Coinbase" matches the built-in CoinbaseExchange
symbol: "BTC-USD",
interval: CandleInterval.SIX_HOURS,
period: "3M",
studies: [new OHLCStudy(), new VolumeStudy(), new SMAStudy({ length: 50 }), rsi],
});
// Show the RSI's descriptor, and show it again whenever settings are applied:
// descriptorApplied fires after every applyDescriptor, from code or from a settings form
const showDescriptor = () => (descriptorView.textContent = JSON.stringify(rsi.getDescriptor(), null, 2));
rsi.descriptorApplied.subscribe(showDescriptor);
showDescriptor();
toolbar.append(
// An input: the RSI is recalculated
button("RSI period 7", () => setStudySetting(rsi, EDescriptorSectionName.INPUTS, "period", 7)),
button("RSI period 21", () => setStudySetting(rsi, EDescriptorSectionName.INPUTS, "period", 21)),
// A style: the RSI line is recoloured, with no recalculation
button("RSI line amber", () => setStudySetting(rsi, EDescriptorSectionName.STYLES, "strokeColor", "#ff9f1c")),
// getDefaultDescriptor() is the study's settings as first attached
button("Reset RSI", () => rsi.applyDescriptor(rsi.getDefaultDescriptor()))
);
// When the page goes away: financeChartPanel.cleanup();
return financeChartPanel;
}
function button(text: string, onClick: () => void) {
const b = document.createElement("button");
b.textContent = text;
b.onclick = onClick;
Object.assign(b.style, buttonStyle);
return b;
}
// The toolbar uses SciTrader's UI colours: its --st-ui-* CSS variables, with the stylesheet's defaults
const toolbarStyle: Partial<CSSStyleDeclaration> = {
display: "flex",
flexWrap: "wrap",
alignItems: "center",
gap: "8px",
padding: "8px",
background: "var(--st-ui-background, #2b2839)",
borderBottom: "1px solid var(--st-ui-divider, rgba(255,255,255,0.1))",
};
const buttonStyle: Partial<CSSStyleDeclaration> = {
padding: "4px 10px",
border: "1px solid var(--st-ui-divider, rgba(255,255,255,0.1))",
borderRadius: "6px",
background: "var(--st-ui-surface, #373447)",
color: "var(--st-ui-text, #ffffff)",
font: "inherit",
fontSize: "13px",
cursor: "pointer",
};
const descriptorStyle: Partial<CSSStyleDeclaration> = {
padding: "8px 12px",
background: "var(--st-ui-background, #2b2839)",
borderLeft: "1px solid var(--st-ui-divider, rgba(255,255,255,0.1))",
color: "var(--st-ui-text-muted, #9da2bc)",
fontSize: "11px",
};
createChart();
React Example: Changing Study Settings from Code
The same chart in React. The descriptor panel is React state, updated from descriptorApplied in an effect.
The code for this example is found below.
- React
import "scichart-scitrader/scitrader.css";
import * as React from "react";
import {
CandleInterval,
CoinbaseExchange,
defaultExchangeProvider,
EDescriptorSectionName,
idbPriceStore,
ISciFinanceChartPanelConfig,
IStudy,
OHLCStudy,
RSIStudy,
SMAStudy,
VolumeStudy,
} from "scichart-scitrader";
import { SciFinanceChartView } from "scichart-scitrader-react";
// Register a data source, once, at app startup
defaultExchangeProvider.registerExchange(CoinbaseExchange, idbPriceStore);
// Change one setting of a live study, in code.
// A study's settings are its descriptor: an "inputs" section (periods, levels) and a "styles"
// section (colours, thickness), each a set of named controls holding their value in `default`.
// Copy the descriptor with one value changed and apply it: built-in studies update in place
function setStudySetting(study: IStudy, section: EDescriptorSectionName, control: string, value: string | number) {
const descriptor = study.getDescriptor();
const controls = descriptor[section].controls;
study.applyDescriptor({
...descriptor,
[section]: { controls: { ...controls, [control]: { ...controls[control], default: value } } },
});
}
export function StudySettingsChart() {
// Create the studies and config once per mounted chart: studies are live objects bound to one chart
const { rsi, config } = React.useMemo(() => {
const rsi = new RSIStudy({ length: 14 });
const config: ISciFinanceChartPanelConfig = {
exchangeName: CoinbaseExchange.name, // name="Coinbase" matches the built-in CoinbaseExchange
symbol: "BTC-USD",
interval: CandleInterval.SIX_HOURS,
period: "3M",
studies: [new OHLCStudy(), new VolumeStudy(), new SMAStudy({ length: 50 }), rsi],
};
return { rsi, config };
}, []);
// The RSI's descriptor, shown as JSON, and shown again whenever settings are applied:
// descriptorApplied fires after every applyDescriptor, from code or from a settings form.
// Keep a JSON string in state, not the descriptor: getDescriptor() refills and returns the
// same object each time, so React would see no change
const toJson = () => JSON.stringify(rsi.getDescriptor(), null, 2);
const [descriptorJson, setDescriptorJson] = React.useState(toJson);
React.useEffect(() => {
const onApplied = () => setDescriptorJson(toJson());
rsi.descriptorApplied.subscribe(onApplied);
return () => rsi.descriptorApplied.unsubscribe(onApplied);
}, [rsi]);
// Fills its parent, so give the parent a height
return (
<div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
<div style={toolbarStyle}>
{/* An input: the RSI is recalculated */}
<button style={buttonStyle} onClick={() => setStudySetting(rsi, EDescriptorSectionName.INPUTS, "period", 7)}>
RSI period 7
</button>
<button style={buttonStyle} onClick={() => setStudySetting(rsi, EDescriptorSectionName.INPUTS, "period", 21)}>
RSI period 21
</button>
{/* A style: the RSI line is recoloured, with no recalculation */}
<button
style={buttonStyle}
onClick={() => setStudySetting(rsi, EDescriptorSectionName.STYLES, "strokeColor", "#ff9f1c")}
>
RSI line amber
</button>
{/* getDefaultDescriptor() is the study's settings as first attached */}
<button style={buttonStyle} onClick={() => rsi.applyDescriptor(rsi.getDefaultDescriptor())}>
Reset RSI
</button>
</div>
<div style={{ display: "flex", flex: 1, minHeight: 0 }}>
<div style={{ flex: 1, minWidth: 0 }}>
<SciFinanceChartView config={config} />
</div>
<pre style={descriptorStyle}>{descriptorJson}</pre>
</div>
</div>
);
}
// The toolbar uses SciTrader's UI colours: its --st-ui-* CSS variables, with the stylesheet's defaults
const toolbarStyle: React.CSSProperties = {
display: "flex",
flexWrap: "wrap",
alignItems: "center",
gap: 8,
padding: 8,
background: "var(--st-ui-background, #2b2839)",
borderBottom: "1px solid var(--st-ui-divider, rgba(255,255,255,0.1))",
};
const buttonStyle: React.CSSProperties = {
padding: "4px 10px",
border: "1px solid var(--st-ui-divider, rgba(255,255,255,0.1))",
borderRadius: 6,
background: "var(--st-ui-surface, #373447)",
color: "var(--st-ui-text, #ffffff)",
font: "inherit",
fontSize: 13,
cursor: "pointer",
};
const descriptorStyle: React.CSSProperties = {
width: 320,
margin: 0,
padding: "8px 12px",
overflow: "auto",
background: "var(--st-ui-background, #2b2839)",
borderLeft: "1px solid var(--st-ui-divider, rgba(255,255,255,0.1))",
color: "var(--st-ui-text-muted, #9da2bc)",
fontSize: 11,
};
Letting Users Edit Settings: StudySettingsForm and StudyList
Two ready-made UI components edit a study's descriptor for you:
StudySettingsFormdraws one study's settings as a form, with a field for each control: number boxes, dropdowns, colour pickers and line styles. Edits apply as they are made.StudyListlists the chart's studies; each opens its settings form, and × removes the study.
// React
import { StudyList, StudySettingsForm } from "scichart-scitrader-react";
<StudySettingsForm study={rsi} /> // one study's settings
<StudyList chart={financeChartPanel.financeApi} title="Studies" /> // every study on the chart
They work with any study, including your own. A settings form shows values applied from code, too. See Study Settings Form and Study List for their options, styling and live examples.
Where to read next
- Study Settings Form and Study List: let users edit study settings.
- Creating Custom Studies: give your own study settings.
- Save and Restore: settings are saved with the chart.