Finance scenario
Capital markets workflow showing intraday quote monitor — synthetic feed, flashing cells, and observable alerts
Your Role
You are on the desk watching a short list of liquid names during the session.
import {AdaptableOptions} from '@adaptabletools/adaptable';
import {LiveQuote} from './rowData';
import {isLiveFeedActive, startLiveFeed, stopLiveFeed} from './livePriceFeed';
export const adaptableOptions: AdaptableOptions<LiveQuote> = {
primaryKey: 'id',
adaptableId: 'Showcase: Live Price Monitor',
userName: 'Desk Trader',
dashboardOptions: {
customToolbars: [
{
name: 'FeedToolbar',
title: 'Feed',
toolbarButtons: [
{
label: 'Start feed',
buttonStyle: {tone: 'success', variant: 'raised'},
disabled: () => isLiveFeedActive(),
onClick: () => startLiveFeed(),
},
{
label: 'Stop feed',
buttonStyle: {tone: 'warning', variant: 'outlined'},
disabled: () => !isLiveFeedActive(),
onClick: () => stopLiveFeed(),
},
],
},
],
},
initialState: {
Dashboard: {
Tabs: [
{
Name: 'Monitor',
Toolbars: ['FeedToolbar', 'Layout', 'Alert', 'SystemStatus'],
},
],
ModuleButtons: ['Layout', 'Alert', 'FlashingCell', 'CalculatedColumn', 'StyledColumn', 'SettingsPanel'],
},
StatusBar: {
StatusBars: [
{
Key: 'Center Panel',
StatusBarPanels: ['Alert', 'SystemStatus'],
},
],
},
Theme: {CurrentTheme: 'dark'},
NamedQuery: {
NamedQueries: [
{
Name: 'Active Movers',
BooleanExpression: 'ABS([changePct]) > 0.75',
},
],
},
Layout: {
CurrentLayout: 'Live Monitor',
Layouts: [
{
Name: 'Live Monitor',
AutoSizeColumns: true,
TableColumns: [
'symbol',
'name',
'sector',
'open',
'last',
'trend',
'changePct',
'sessionTicks',
'volume',
],
ColumnSizing: {
trend: {Width: 52},
sessionTicks: {Width: 168},
},
ColumnSorts: [{ColumnId: 'changePct', SortOrder: 'Desc'}],
},
{
Name: 'Active Movers',
AutoSizeColumns: true,
TableColumns: ['symbol', 'last', 'trend', 'changePct', 'sessionTicks', 'volume'],
ColumnSizing: {
trend: {Width: 52},
sessionTicks: {Width: 168},
},
GridFilter: {
Expression: 'QUERY("Active Movers")',
},
},
],
},
FlashingCell: {
FlashingCellDefinitions: [
{
Name: 'flash-last',
Scope: {ColumnIds: ['last']},
Rule: {BooleanExpression: 'ANY_CHANGE()'},
},
{
Name: 'flash-volume',
Scope: {ColumnIds: ['volume']},
Rule: {BooleanExpression: 'ANY_CHANGE()'},
},
],
},
CalculatedColumn: {
CalculatedColumns: [
{
ColumnId: 'trend',
FriendlyName: 'Trend',
Query: {
ScalarExpression:
"CASE WHEN [changePct] > 0 THEN 'Up' WHEN [changePct] < 0 THEN 'Down' ELSE 'Flat' END",
},
CalculatedColumnSettings: {
DataType: 'text',
Resizable: false,
Width: 52,
},
},
],
},
StyledColumn: {
StyledColumns: [
{
Name: 'trend Icon',
ColumnId: 'trend',
IconStyle: {
Preset: 'Trend',
ToolTipText: ['CellValue'],
Size: 18,
Gap: 4,
},
},
{
Name: 'changePct gradient',
ColumnId: 'changePct',
GradientStyle: {
ZeroCentred: {
NegativeColor: '#ff5252',
PositiveColor: 'var(--ab-color-success)',
},
},
},
{
ColumnId: 'sessionTicks',
Name: 'sessionTicks Sparkline',
SparklineStyle: {
options: {
type: 'line',
stroke: 'rgb(100, 220, 140)',
strokeWidth: 2.5,
padding: {top: 6, bottom: 6},
marker: {
enabled: true,
size: 3,
shape: 'circle',
fill: 'rgb(100, 220, 140)',
stroke: 'rgb(180, 255, 200)',
},
},
},
},
],
},
FormatColumn: {
FormatColumns: [
{
Name: 'price-dollar',
Scope: {ColumnIds: ['open', 'last']},
DisplayFormat: 'Dollar',
},
{
Name: 'format-pct',
Scope: {ColumnIds: ['changePct']},
DisplayFormat: {
Formatter: 'NumberFormatter',
Options: {Suffix: '%', FractionDigits: 2},
},
},
{
Name: 'format-volume',
Scope: {ColumnIds: ['volume']},
DisplayFormat: {
Formatter: 'NumberFormatter',
Options: {FractionDigits: 0},
},
},
],
},
Alert: {
AlertDefinitions: [
{
Name: 'Choppy symbol',
MessageType: 'Info',
MessageHeader: 'Choppy quote',
MessageText: 'Last changed 3+ times in 45 seconds on this row',
Scope: {All: true},
Rule: {
ObservableExpression:
"ROW_CHANGE(COUNT([last], 3), TIMEFRAME('45s'))",
},
AlertProperties: {
DisplayNotification: true,
DisplaySystemStatusMessage: true,
},
},
{
Name: 'Session high',
MessageType: 'Success',
MessageHeader: 'New high',
MessageText: 'Last is the highest seen on this row in the last 5 minutes',
Scope: {All: true},
Rule: {
ObservableExpression:
"ROW_CHANGE(MAX([last]), TIMEFRAME('5m'))",
},
AlertProperties: {
DisplayNotification: true,
},
},
{
Name: 'Stale row quote',
MessageType: 'Warning',
MessageHeader: 'Stale quote',
MessageText: 'No Last update on this row for 20 seconds',
Scope: {All: true},
Rule: {
ObservableExpression:
"ROW_CHANGE(NONE([last]), TIMEFRAME('20s'))",
},
AlertProperties: {
DisplayNotification: true,
DisplaySystemStatusMessage: true,
},
},
{
Name: 'Feed paused',
MessageType: 'Error',
MessageHeader: 'Feed stalled',
MessageText: 'No Last updates anywhere in the grid for 12 seconds',
Scope: {All: true},
Rule: {
ObservableExpression:
"GRID_CHANGE(NONE([last]), TIMEFRAME('12s'))",
},
AlertProperties: {
DisplayNotification: true,
DisplaySystemStatusMessage: true,
},
},
{
Name: 'Busy market',
MessageType: 'Info',
MessageHeader: 'Active market',
MessageText: 'Last updated 8+ times grid-wide in 30 seconds',
Scope: {All: true},
Rule: {
ObservableExpression:
"GRID_CHANGE(COUNT([last], 8), TIMEFRAME('30s'))",
},
AlertProperties: {
DisplayNotification: true,
},
},
],
},
},
};Read-onlyLoading demo…