# Messages and event handlers

You can listen for changes in prices, the order list, account metrics etc using an OnMessage() handler. For example:

&#x20;

Framework.OnMessage = function(Msg) {

&#x20;      if (Msg.is(Liquid.MessageTypes.PRICE)) {

&#x20;                  … update a quote board

&#x20;      }

};

&#x20;

Some types of message such as changes to account metrics are issued automatically. Other types of message, such as prices or account history, must be specifically requested by your widget/script/UDIX.

&#x20;

By the time that message handlers are called, the framework's objects and collections have already been updated. For example, if you receive an ORDER\_OPEN message, the new order(s) will already be present in the Framework.Orders collection.

&#x20;

As well as using the main OnMessage handler, you can also define individual handlers for some types of message. For example, you can define an OnPriceChange function. All price changes are then sent to that function as well as to the main OnMessage handler.

&#x20;

It's possible for your code to have multiple message handlers (each of which receives all messages). You can do the following as well as or instead of using OnMessage().

&#x20;

var handler1 = Framework.AddMessageHandler(function (Msg) { … a handler function});

var handler2 = Framework.AddMessageHandler(function (Msg) { … a second handler });

&#x20;

The return value from AddMessageHandler() is an ID which assists with the common Javascript problem of detaching anonymous functions. If you only need a message handler temporarily, you can store its ID and then later disconnect it using RemoveMessageHandler():

&#x20;

Framework.RemoveMessageHandler(handler1);

&#x20;

Note: you may observe that _everything_ passes through OnMessage: initial load, results of trading actions etc. It's possible to handle the results of something like a trading action by watching OnMessage rather than supplying a callback function to SendOrder(). But there's generally no good reason to do that, and this section of the guide only covers the expected uses of OnMessage.

&#x20;

### 4.1      Multiple updates in a single message <a href="#toc104559758" id="toc104559758"></a>

The framework can issue multiple updates in a single message. For example, a single message and a single call to OnMessage can contain changes to multiple prices and also updates to the order list.

&#x20;

Therefore, you should generally process messages along the following lines:

&#x20;

Framework.OnMessage = function(Msg) {

&#x20;      if (Msg.is(Liquid.MessageTypes.PRICE)) {

&#x20;                  … update a quote board

&#x20;      }

&#x20;

&#x20;      if (Msg.is(\[Liquid.MessageTypes.ORDER\_OPEN, Liquid.MessageTypes.ORDER\_CLOSE])) {

&#x20;                  … update a trade list

&#x20;      }

};

&#x20;

The following – else-if instead of if-if – is not safe because a message may be both a price update and an order update, and the order update will be ignored by the code if the message is also a price update:

&#x20;

Framework.OnMessage = function(Msg) {

&#x20;      if (Msg.is(Liquid.MessageTypes.PRICE)) {

&#x20;                  … update a quote board

&#x20;    &#x20;

&#x20;      // NOT SAFE!

&#x20;      } else if (Msg.is(\[Liquid.MessageTypes.ORDER\_OPEN, Liquid.MessageTypes.ORDER\_CLOSE])) {

&#x20;                  … update a trade list

&#x20;      }

};

&#x20;

### 4.2      The Liquid.Message object <a href="#toc104559759" id="toc104559759"></a>

The parameter which is passed to OnMessage() is an Liquid.Message object. This is a Dictionary, because a message can contain multiple types of update.

&#x20;

In addition to the list of message-types in the message, which you can test using the Dictionary's is() or has(), there can be further properties in the object depending on the type(s) of message. For example, a PRICE message will contain a quotes\[] array of new prices. These extra properties are described below.

&#x20;

### 4.3      Types of message <a href="#toc104559760" id="toc104559760"></a>

The types of message which you can receive via OnMessage() are as follows, from the Liquid.MessageTypes enumeration:

&#x20;

| Liquid.MessageTypes.       | Description                                                                                                                                      |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| PRICE                      | Update to one or more prices                                                                                                                     |
| ORDER\_OPEN                | New pending order or open trade                                                                                                                  |
| ORDER\_CHANGE              | Change to a pending order or open trade (including non-trading changes such as fluctuating profit on an open trade)                              |
| ORDER\_CLOSE               | Closure of an open trade or cancellation of a pending order                                                                                      |
| POSITION\_CHANGE           | Change to a net position                                                                                                                         |
| ACCOUNT\_METRICS           | Change to account metrics such as balance or margin usage                                                                                        |
| ACCOUNT\_HISTORY           | Initial load or subsequent change to the account history                                                                                         |
| MARKET\_DEPTH              | Update to market depth                                                                                                                           |
| ORDER\_BOOK                | Update to order book                                                                                                                             |
| MAILBOX                    | Event within Liquid Charts Pro's internal mail system                                                                                            |
| THEME                      | Change by the user to the software's graphical theme                                                                                             |
| CATEGORY\_SETTINGS\_CHANGE | Change to the category settings of your widget, script, or UDIX                                                                                  |
| WIDGET\_CONTEXT\_CHANGE    | Change of context – synchronisation of markets and/or timeframes – in the Liquid Charts Pro page container                                       |
| BROADCASTx                 | Range of messages, from BROADCAST1 to BROADCAST10, which widgets, scripts, or UDIXes can use to broadcast their existence to other components    |
| GENERICx                   | Range of messages, from GENERIC1 to GENERIC10, which a widget, script, or UDIX can use to send a direct message to a component whose ID it knows |

&#x20;

### 4.4      Liquid.MessageTypes.PRICE and OnPriceChange <a href="#extern_price_message" id="extern_price_message"></a>

You need to request messages for the prices you are interested in. You don't automatically receive notifications about all price changes.

&#x20;

Once you have requested price updates, there are two ways of receiving and processing them:

&#x20;

·      By using the main OnMessage handler, and listening for the PRICE message

·      By defining an OnPriceChange handler

&#x20;

There is a subtle difference between these two routes:

&#x20;

·      PRICE messages may contain other instruments, in addition to those you have requested, in their quotes\[] array.

·      The OnPriceChange handler is guaranteed only to be called in relation to the market(s) you have requested.

&#x20;

#### 4.4.1    PRICE messages in OnMessage <a href="#id-4.4.1_price_messages" id="id-4.4.1_price_messages"></a>

Whenever there is a change to a requested price, the main OnMessage handler receives a PRICE message. For example:

&#x20;

Framework.OnMessage = function(Msg) {

&#x20;      if (Msg.is(Liquid.MessageTypes.PRICE)) {

&#x20;                  Msg.quotes\[] contains a list of price changes

&#x20;      }

&#x20;      …

};

&#x20;

The Liquid.Message object will contain a quotes\[] array listing the changed prices. You may receive notifications for other markets in addition to the one(s) you have requested. For example, if you have only requested prices for a single market, you cannot rely on quotes.length being 1.

&#x20;

Each object in the quotes\[] array has the following properties:

&#x20;

| Property     | Description                                                                        |
| ------------ | ---------------------------------------------------------------------------------- |
| time         | Time of the most recent quote                                                      |
| bid          | Latest bid price                                                                   |
| ask          | Latest ask price                                                                   |
| high         | High of the current period. Availability depends on account features.              |
| low          | Low of the current period. Availability depends on account features.               |
| change       | Change amount during the current period. Availability depends on account features. |
| changePc     | Change amount as a percentage. Availability depends on account features.           |
| updateMarker | See below                                                                          |

&#x20;

You can react to the changed prices either by looking at the quotes\[] array, or by looking at the prices in the Framework.Instruments collection which will already have been updated.

&#x20;

The updateMarker is a bit-mask of what is changing in a quote. This is designed to help you minimise the work in updating a user interface. For example, if the bit-mask contains FLAG\_PRICE\_BID but not FLAG\_PRICE\_ASK, then you know that you only need to update the display of the bid price. You don't need to make the browser to do extra work updating an ask price which hasn't changed.

&#x20;

The possible flags are members of the Liquid.UpdateFlags enumeration:

&#x20;

| Liquid.UpdateFlags. | Description               |
| ------------------- | ------------------------- |
| BID                 | Bid has changed           |
| ASK                 | Ask has changed           |
| HIGH                | High has changed          |
| LOW                 | Low has changed           |
| CHANGEONDAY         | Change-on-day has changed |

&#x20;

#### 4.4.2    OnPriceChange handler <a href="#id-4.4.2_onpricechange_handler" id="id-4.4.2_onpricechange_handler"></a>

Instead of using the main OnMessage handler, you may find it easier to watch price changes using an OnPriceChange handler. If defined, this is called by the framework with each individual price which is changing:

&#x20;

Framework.OnPriceChange = function(quote) {

&#x20;      // The quote object contains the same time, bid, ask etc properties listed above

};

&#x20;

### 4.5      Liquid.MessageTypes.ORDER\_x and OnOrderX handlers <a href="#id-4.5_fxb.messagetypes.order_x" id="id-4.5_fxb.messagetypes.order_x"></a>

There are two ways of tracking changes in the order list (which includes both pending orders and open trades):

&#x20;

·      By using the main OnMessage handler to listen for the ORDER\_OPEN, ORDER\_CHANGE, and ORDER\_CLOSE messages

·      By defining any or all of OnOrderOpen, OnOrderChange, and OnOrderClose handlers

&#x20;

#### 4.5.1    ORDER\_x messages in OnMessage <a href="#id-4.5.1_order_x_messages" id="id-4.5.1_order_x_messages"></a>

The ORDER\_OPEN, ORDER\_CHANGE, and ORDER\_CLOSE messages are issued on changes to the order list (which includes both pending orders and open trades).

&#x20;

ORDER\_CHANGE is issued for changes in the current price and/or profit on an open trade, as well as trading actions such as moving its stop-loss.

&#x20;

The Liquid.Message object will contain arrays listing the new/changed/closed orders:

&#x20;

| Liquid.MessageTypes. | Array            |
| -------------------- | ---------------- |
| ORDER\_OPEN          | ordersOpened\[]  |
| ORDER\_CHANGE        | ordersChanged\[] |
| ORDER\_CLOSE         | ordersClosed\[]  |

&#x20;

A single message from the framework can contain multiple updates, and therefore the message may contain all of these arrays. For example:

&#x20;

&#x20;Framework.OnMessage = function(Msg) {

&#x20;      if (Msg.is(Liquid.MessageTypes.ORDER\_OPEN)) {

&#x20;                  … process changes in Msg.ordersOpened\[]

&#x20;      }

&#x20;

&#x20;      if (Msg.is(Liquid.MessageTypes.ORDER\_CLOSE)) {

&#x20;                  … process changes in Msg.ordersClosed\[]

&#x20;      }

};

&#x20;

Each item in one of these arrays is simply an Liquid.Order object describing the new/changed/closed order or trade.

&#x20;

You can react to the changes either by looking at the arrays of orders, or by looking at the Framework.Orders collection which will already have been updated.

&#x20;

However, in addition to the standard members of Liquid.Order, each item in the arrays also has an updateMarker. This is a bit-mask describing what has changed about the order. Particularly for changes rather than opens and closes, this is designed to help you minimise the work in updating a user interface, avoiding updates to HTML elements which don't need to be changed.

&#x20;

The possible flags are members of the Liquid.UpdateFlags enumeration:

&#x20;

| Liquid.UpdateFlags.       | Description                                                                                                                                                        |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| FLAG\_ORDER\_NEW          | Order is new (should only exist in ordersOpened\[] array)                                                                                                          |
| FLAG\_ORDER\_TYPE         | Change in orderType – for example, when logged in to a back-end platform where an order can change from pending to filled without changing ticket/reference number |
| FLAG\_ORDER\_VOLUME       | Volume has changed, for example as a result of a partial close                                                                                                     |
| FLAG\_ORDER\_PROFIT       | Profit has changed                                                                                                                                                 |
| FLAG\_ORDER\_SLTP         | Stop-loss and/or take-profit has changed                                                                                                                           |
| FLAG\_ORDER\_CURRENTPRICE | Current price (closePrice) has changed                                                                                                                             |
| FLAG\_ORDER\_OPENPRICE    | Open price has changed – alteration to the entry price on a pending order                                                                                          |
| FLAG\_ORDER\_COMMENT      | Order comment has changed                                                                                                                                          |
| FLAG\_ORDER\_OTHER        | Any other change to order properties                                                                                                                               |
| FLAG\_ORDER\_CLOSED       | Order is closed/cancelled (should only exist in ordersClosed\[] array)                                                                                             |

&#x20;

#### 4.5.2    OnOrderX handlers <a href="#id-4.5.2_onorderx_handlers" id="id-4.5.2_onorderx_handlers"></a>

Instead of using the main OnMessage handler, you can also track changes in the order list using the functions OnOrderOpen, OnOrderChange, and OnOrderClose. (You don't have to define all three of these. If you are only interested in new opens, then you only need to define OnOrderOpen).

&#x20;

Each of these handlers receives as a parameter the individual order which is being opened, changed, or closed. For example:

&#x20;

Framework.OnOrderOpen = function(newOrder)

{

&#x20;      // newOrder is an Liquid.Order describing the new trade or pending order

};

&#x20;

### 4.6      Liquid.MessageTypes.POSITION\_CHANGE and OnPositionChange <a href="#extern_position_message" id="extern_position_message"></a>

You can listen for changes in the changes in the Framework.Positions list in two ways:

&#x20;

·      By using the main OnMessage handler to listen for the POSITION\_CHANGE message

·      By defining an OnPositionChange handler

&#x20;

In both cases, position updates are not issued for changes in profit (or current price). They are only issued for changes in the net position caused by an order opening or closing. If you want to update a display of the profit on a net position, then you need to do something such as watching the market's price as a prompt telling you that the profit will have changed.

&#x20;

#### 4.6.1    POSITION\_CHANGE message in OnMessage <a href="#id-4.6.1_position_change_message" id="id-4.6.1_position_change_message"></a>

The POSITION\_CHANGE message is issued about changes in the Framework.Positions list.

&#x20;

The Liquid.Message object will contain a positionsChanged\[] array listing the Liquid.Position objects which have changed. You can react to the changes either by looking at the positionsChanged\[] array, or by looking at the Framework.Positions collection which will already have been updated.

&#x20;

#### 4.6.2    OnPositionChange handler <a href="#id-4.6.2_onpositionchange_handler" id="id-4.6.2_onpositionchange_handler"></a>

Instead of using the main OnMessage handler, you can also track changes in the position list by using an OnPositionChange handler. If defined, this is called by the framework for each change in a position:

&#x20;

Framework.OnPositionChange = function(position) {

&#x20;      // An Liquid.Position update describing the change

};

&#x20;

### 4.7.     Liquid.MessageTypes.ACCOUNT\_METRICS and OnAccountMetrics <a href="#extern_accountmetrics_message" id="extern_accountmetrics_message"></a>

You can listen for changes in the metrics in Framework.Account – change in floating P/L, margin usage etc – in two ways:

&#x20;

·      By using the main OnMessage handler to listen for the ACCOUNT\_METRICS message

·      By defining an OnAccountMetrics handler

&#x20;

#### 4.7.1    ACCOUNT\_METRICS message in OnMessage <a href="#id-4.7.1_account_metrics_message" id="id-4.7.1_account_metrics_message"></a>

The ACCOUNT\_METRICS message is issued about changes to the metrics in Framework.Account – change in floating P/L, margin usage etc.

&#x20;

The Liquid.Message object will contain an accountMetrics object. The properties of Msg.accountMetrics correspond to the properties in the Framework.Account, but it only contains values which are changing. For example, for a change of floating P/L without a new closed trade which affects the balance, the accountMetrics will include a floatingPL property but not a balance property.

&#x20;

You can also inspect what has changed using an updateMarker in the accountMetrics. This is a bit-mask describing which metrics have changed. The possible flags are members of the Liquid.UpdateFlags enumeration:

&#x20;

| Liquid.UpdateFlags.       | Description                                                           |
| ------------------------- | --------------------------------------------------------------------- |
| FLAG\_ACCOUNT\_FLOATINGPL | Change to floating P/L                                                |
| FLAG\_ACCOUNT\_EQUITY     | Change to equity (should always also imply FLAG\_ACCOUNT\_FLOATINGPL) |
| FLAG\_ACCOUNT\_BALANCE    | Change to balance                                                     |
| FLAG\_ACCOUNT\_USEDMARGIN | Change to margin in use                                               |
| FLAG\_ACCOUNT\_FREEMARGIN | Change to free margin                                                 |
| FLAG\_ACCOUNT\_CREDIT     | Change to account credit                                              |

&#x20;

#### 4.7.2    OnAccountMetrics handler <a href="#id-4.7.2_onaccountmetrics_handler" id="id-4.7.2_onaccountmetrics_handler"></a>

Instead of using the main OnMessage handler, you can also track changes in the account metrics such as balance and floating P/L by using an OnAccountMetrics handler. If defined, this is called by the framework each time that any of the metrics changes:

&#x20;

Framework.OnAccountMetrics = function(accountMetrics) {

&#x20;      // Receives the same accountMetrics object as in OnMessage

};

&#x20;

The parameter to the OnAccountMetrics handler is the same value inside an ACCOUNT\_METRICS message.

&#x20;

### 4.8      Liquid.MessageTypes.ACCOUNT\_HISTORY <a href="#toc104559765" id="toc104559765"></a>

The ACCOUNT\_HISTORY message is issued on initial load of the account history, followed by each addition of a new closed order or credit movement. You need to request account history; it is not issued automatically.

&#x20;

By the time that your message handler receives ACCOUNT\_HISTORY, the Framework.TradeHistory collection will already have been updated with the changes.

&#x20;

You can inspect which transactions are being added by looking at the history\[] array in the Liquid.Message object. Like the Framework.TradeHistory collection, each item in the history\[] array is an Liquid.Order object describing the closed trade/order or credit movement.

&#x20;

### 4.9      Liquid.MessageTypes.MARKET\_DEPTH <a href="#toc104559766" id="toc104559766"></a>

The MARKET\_DEPTH message is sent in response to a request for market depth. It can be processed either in OnMessage() or using an asynchronous callback to RequestMarketDepth(). Market depth must be explicitly requested; it is not sent automatically.

&#x20;

### 4.10    Liquid.MessageTypes.ORDER\_BOOK <a href="#toc104559767" id="toc104559767"></a>

The ORDER\_BOOK message is sent in response to a request for order book. It can be processed either in OnMessage() or using an asynchronous callback to RequestOrderBook(). Order book must be explicitly requested; it is not sent automatically.

&#x20;

### 4.11    Liquid.MessageTypes.MAILBOX <a href="#toc104559768" id="toc104559768"></a>

The MAILBOX message is a notification of a change in Liquid Charts Pro's mail system – not just a new message, or deletions, but also a message being opened and treated as read.

&#x20;

MAILBOX messages must be specifically requested. They are not sent automatically by default.

&#x20;

MAILBOX messages contain a mail\[] array. This always (re-)lists all messages in the mailbox, not just additions.

&#x20;

### 4.12    Liquid.MessageTypes.THEME <a href="#toc104559769" id="toc104559769"></a>

(This section is irrelevant to scripts and UDIXes because they have no user interface of their own. It is only applicable to widgets.)

&#x20;

The user can change the graphical theme of the software – e.g. from dark to light – while it is running, without a restart. Therefore, the theme can change while your widget is running.

&#x20;

The THEME message notifies you that this has happened. The Liquid.Message object will contain a Theme object, but it is simplest to inspect the change just by using Framework.Theme.

&#x20;

### 4.13    Liquid.MessageTypes.CATEGORY\_SETTINGS\_CHANGE <a href="#toc104559770" id="toc104559770"></a>

The CATEGORY\_SETTINGS\_CHANGE message is received by all instances of your widget, script, or UDIX when one instance saves changes using Framework.SaveCategorySettings().

&#x20;

The message is sent to the instance which saved the change as well as to any other running instances of the widget. The message includes a categorySettings property containing the new settings, but these are also available via Framework.categorySettings.

&#x20;

### 4.14    Liquid.MessageTypes.WIDGET\_CONTEXT\_CHANGE <a href="#toc104559771" id="toc104559771"></a>

The WIDGET\_CONTEXT\_CHANGE message is received by a widget (only, not a script or UDIX) under the following circumstances:

&#x20;

·      The widget has been added to the Liquid Charts Pro page container

·      The user has chosen to synchronize the markets and/or timeframes on the page, and another widget changes the market or timeframe

·      Or, some component uses SetCurrentPageInstrument() or SetCurrentPageTimeframe()

&#x20;

See the section on handling context for more information.

&#x20;

### 4.15    Liquid.MessageTypes.BROADCASTx and Liquid.MessageTypes.GENERICx <a href="#toc104559772" id="toc104559772"></a>

The message types from BROADCAST1 to BROADCAST10 and from GENERIC1 to GENERIC10 are designed for transient, ad hoc messaging between different widgets, scripts, and UDIXes.

&#x20;

BROADCASTx messages can be sent out without a specified recipient ID (a \_to in the message). GENERICx messages require a recipient.

&#x20;

## &#x20;<a href="#extern_technical_analysis" id="extern_technical_analysis"></a>
