The Universal Dashboard consists of 2 logical parts:

- front-end responsible for rendering on-chart table with signals or estimated values
- back-end, based on expression calculation engine, which feeds the table with data

Expressions can be used to check market conditions via technical indicators and timeseries functors, arbitrary analytical arithmetics, logical branching, and results visualization. Results can be shown as numbers or converted to descriptive marks. A user can be notified about detected signals.

X and Y axes can iterate through symbols, timeframes, and signals (expressions) in any combination and orientation:

- symbols vs timeframes showing one specific signal
- timeframes vs symbols showing one specific signal
- symbols vs different signals showing on one specific timeframe
- different signals vs symbols showing on one specific timeframe
- timeframes vs different signals showing for one specific symbol
- different signals vs timeframes showing for one specific symbol

Please refer to the product page for input parameters. In case input parameters are incorrect, the program shows an alert and writes details in the log.

### Supported operators (in the order of priority)

- ! — logical negation
- -, + — unary minus and plus
- () — grouping with parentheses
- *, /, % — multiplication, division and division by modulo
- +, – — addition and subtraction
- >, <, >=, <= — greater than, less than, greater than or equal, less than or equal comparison
- ==, != — equality and non-equality comparison
- &&, || — logical AND and OR (please note that priority is the same, so parentheses should be used)
- ?: — ternary conditional operator that allows you to branch calculations according to logical subexpressions

### Built-in functions (symbol/timeframe independent)

Most of the functions come from MQL5 as is, some with a simplified name.

- abs(value) – fabs
- acos(value) – acos
- acosh(value) – acosh
- asin(value) – asin
- asinh(value) – asinh
- atan(value) – atan
- atanh(value) – atanh
- ceil(value) – ceil
- cos(value) – cos
- cosh(value) – cosh
- exp(value) – exp
- floor(value) – floor
- log(value) – log
- log10(value) – log10
- max(value1, value2) – fmax
- min(value1, value2) – fmin
- mod(dividend, divisor) – fmod
- pow(base, exponent) – pow
- rand() – rand
- round(value) – round
- sin(value) – sin
- sinh(value) – sinh
- sqrt(value) – sqrt
- tan(value) – tan
- tanh(value) – tanh
- now() – TimeCurrent
- valid(value) – MathIsValidNumber
- normalize(value, digits) – NormalizeDouble
- number(value) – safeguard from EMPTY_VALUE and NaN (not a number) values – they are transformed to 0, while all other values returned as is
- int(value) – pseudo casting to integer type, an equivalent of normalize(value, 0)

### Built-in indicators

- iAC( )[1]
- iAD(volume)[1]
- iADX(period)[3]
- iADXWilder(period)[3]
- iAlligator(jawP,jawS,teethP,teethS,lipsP,lipsS,method,price)[3]
- iAMA(period,fast,slow,shift,price)[1]
- iAO( )[1]
- iATR(period)[1]
- iBands(period,deviation,shift,price)[3]
- iBearsPower(period,price)[1]
- iBullsPower(period,price)[1]
- iBWMFI(volume)[1]
- iCCI(period,price)[1]
- iChaikin(fast,slow,method,volume)[1]
- {iCustom}(…)[?]
- iDEMA(period,shift,price)[1]
- iDeMarker(period)[1]
- iEnvelopes(period,method,shift,price,deviation)[3]
- iForce(period,method,volume)[1]
- iFractals( )[2]
- iFrAMA(period,shift,price)[1]
- iGator(jawP,jawS,teethP,teethS,lipsP,lipsS,method,price)[2]
- iIchimoku(tenkan,kijun,senkou)[5]
- iMomentum(period,price)[1]
- iMFI(period,volume)[1]
- iMA(period,shift,method,price)[1]
- iMACD(fast,slow,signal,price)[2]
- iOBV(volume)[1]
- iOsMA(fast,slow,signal,price)[1]
- iRSI(period,price)[1]
- iRVI(period)[2]
- iSAR(step,maximum)[1]
- iStdDev(period,shift,method,price)[1]
- iStochastic(K,D,slowing,method,price)[2]
- iTEMA(period,shift,price)[1]
- iTriX(period,price)[1]
- iVIDyA(momentum,smooth,shift,price)[1]
- iVolumes(volume)[1]
- iWPR(period)[1]

For your convenience, indicator parameters of enum types can be passed not only as values but literals (identifiers), see below.

### Built-in identifiers of indicators’ buffers

- main – 0
- signal – 1

- upper – 1
- lower – 2

- jaw – 1
- teeth – 2
- lips – 3

- tenkan – 1
- kijun – 2
- senkouA – 3
- senkouB – 4
- chikou – 3

- +di – 1
- -di – 2
- plusdi – 1
- minusdi – 2

### Built-in identifiers of indicators’ parameters

- sma – MODE_SMA
- ema – MODE_EMA
- smma – MODE_SMMA
- lwma – MODE_LWMA

- close – PRICE_CLOSE
- open – PRICE_OPEN
- high – PRICE_HIGH
- low – PRICE_LOW
- median – PRICE_MEDIAN
- typical – PRICE_TYPICAL
- weighted – PRICE_WEIGHTED

- lowhigh – STO_LOWHIGH
- closeclose – STO_CLOSECLOSE

- tick – VOLUME_TICK
- real – VOLUME_REAL

### Built-in variables

The variables provides unique internal values which identify condition states shown in the table by corresponding marks (Visual Marks group allows you to assign char codes from PictogramFont for each state). For example, the trivial expression “Positive” will output in the table an icon selected for the Positive mark. More meaningfull expression “iMA01(0,0) – iMA01(0,1) >= 0 ? Positive : Negative” will output one of the 2 marks depending from MA direction on the last bar. For your convenience there exist special functors to produce conjugate marks in an easier way (see below).

The names of the variables are selected just on the “most likely in use” principle, and may not necessarily imply actual meaning of your expressions’ results. You are free to use each variable and corresponding mark to denote your specific trade signals.

- Positive
- Negative
- Rising
- Falling
- Filled
- Blank
- Custom1
- Custom2

Don’t use these variables in calculations, they should be returned from expressions to signalize specific trading condition.

Next variables can be used in expressions.

- Empty – EMPTY_VALUE
- Refresh – input parameter RefreshSeconds

### Built-in functors (symbol/timeframe dependent)

The functors can be divided into 3 special classes: mark generators, alerters, and general purpose.

- markPN(value) – produces Positive (if value > 0) or Negative (if value < 0) variable to generate corresponding mark; if value == 0, it returns Blank
- markRF(value) – produces Rising (if value > 0) or Falling (if value < 0) variable to generate corresponding mark; if value == 0, it returns Blank
- mark(value) – produces Filled for all values except for 0 and EMPTY_VALUE, for the last two it returns Blank

- alert(value, interval) – notifies user by Alert, not frequently than every interval seconds; if interval = -1, activates once per bar at most, if interval = -2 activates upon changed value only (compared to previous calculation of the value, which is implied a subexpression); the function returns the value as is
- push(value, interval) – notifies user by SendNotification, and the rest is the same as for alert
- mail(value, interval) – notifies user by SendMail, and the rest is the same as for alert

- point() – point size of corresponding symbol, SymbolInfoDouble(symbol, SYMBOL_POINT)
- period() – number of seconds in corresponding timeframe, PeriodSeconds()
- newBar() – returns -1 if a new bar detected, Blank otherwise

### Built-in timeseries functors (symbol/timeframe dependent)

These functors are accessors of MQL5 timeseries functions.

- time(bar) – iTime
- open(bar) – iOpen
- high(bar) – iHigh
- low(bar) – iLow
- close(bar) – iClose
- volume(bar) – iVolume, iTickVolume
- realVolume(bar) – iRealVolume
- spread(bar) – iSpread

### Table rendering

Signals are shown in the table under their indices in the inputs SignalNN (for instance, “S01”, “S02”, etc). Optionally, you may assign specific label for each signal – for that purpose you should fill SignalLabels input parameter. It accepts comma-separated list of labels.

If you hover mouse over signal label or index in the table, a popup hint will appear with underlying expression.

Specific signal can be temporary disabled, if a special “comment” symbols are used as the first symbol of the expression. The comments start with ‘#’ or ‘/’.

To highlight axes’ labels in bold or other style, you may select DefaultFontBold other than DefaultFont. By default, they are “Arial” and “Arial Black”. Other examples could be (subject to availability on your PC): “Rockwell” and “Rockwell Extra Bold”, “Segoe UI” and “Segoe UI Semibold”, “Tw Cen MT Condensed” and “Tw Cen MT Condensed Extra Bold”.

### Examples of indicators and signals setup

Here is some examples.

14-period SMA moving average on close prices:

Indicator01=iMA(14,0,sma,close)

It can be used to detect MA direction and display it as Rising/Falling marks:

Signal01=markRF(iMA01(0,0)-iMA01(0,1))

Since MA has only one buffer, we pass 0 as the 1-st parameter in both calls, and specify 0-th and 1-st bars to take the difference. The signal index should not have to be the same as the indicator index. It can be Signal05 or anything else.

Price change percent on last bars (any symbols/timeframe combination) can be expressed via timeseries:

(close(0)/close(1)-1.0)*100.0

Price change in points:

(close(0)-close(1))/point()

If you have WPR setup:

Indicator02=iWPR(14)

then you’ll be able to detect oberbough/oversold states on current 0-th bar like this:

Signal02=iWPR02(0,0)>-20?Custom1:(iWPR02(0,0)<-80?Custom2:Blank)

Custom indicators can be used as well, for example:

Indicator03=silvertrend_signal(3,0)

This is a signal indicator placing sell and buy marks in its 0-th and 1-st buffer respectively. Empty values are stored as zeros (not as EMPTY_VALUE). Then you can use the following expression to generate trading signals according to the indicator readings on the 1-st (completed) bar:

Signal06=alert(markPN(IND03(1,1)-IND03(0,1)),-1)

We use “IND03” notation instead of also possible but more lengthy “silvertrend_signal03(…)”. The second parameter in both call is 1, that is the 1-st bar. If sell buffer (number 1 passed as the first IND03 parameter in the 1-st case) is non-zero and buy buffer (number 0 passed as the first IND03 parameter in the 2-nd case) is zero, the subtraction produces positive value. If buy buffer is non-zero and sell buffer is zero, the subtraction produces negative value. When both buffers hold zero, we’ll get zero. These values are converted into signal marks by means of markPN() call. In turn, it’s encapsulated into alert call, which means that the signals will be alerted once per bar.

The alert text could read, for example:

Signal06(EURUSD, H1)=Positive