Article

Monitoring on an Execution Management System in C#

Zoya Farberov
Developer Advocate Developer Advocate

REDI Monitoring In C#

Introduction

REDI is an execution management system (EMS) allowing to trade equities, futures and options with major brokers, globally.

REDIPlus is a graphical user interface client that interfaces with REDI.

The REDI API is a local, COM-based API, leveraged from VBA/Excel, C#, and partially, from Python. 

REDIPlus desktop has to be running and the local user logged in, in order to interface to REDI via REDI API. 

REDI via API 

At a high level, there are two main types of interaction with REDI via API:

  •   Request submission, such as order or ticket entry, order update or order cancellation
  •   Monitoring or subscription, that entails subscribing to the notification of the changes to the entities within REDI, such as changes to orders, positions, market data

This article will focus on and describe the monitoring of REDI objects in C#.

When Do We Use Monitoring in REDI?

Monitoring is a key functionality within REDI if we are planning to integrate via API.

Some common use cases that require REDI monitoring integration are:

  •   Submission of an order, if it requires to consequently confirm its state
  •   Keeping track of a portfolio in terms of positions, values, other characteristics 
  •   Accessing REDI Market data

What Is In Common

Monitoring code interacts with REDI CacheControl.

The following steps are necessary to affect monitoring of REDI via CacheControl class:

    	
            

myCache = new CacheControl();          // create CacheControl object

myCache.CacheEvent += myCacheHandler;  // define and register an event handler

mySubmit();                            // trigger monitoring of a specific type

We create a CacheControl, specify an event handler callback code that will be triggered on CacheEvents, and start our REDI event subscription.

In myCacheHandler we receive and process the CacheEvents based on the action: 

    	
            

private void myCacheHandler(int action, int row) {

    

   if (row >= 0) {

       switch (action) {

                

How To Monitor Orders

Definition:

Submit(string table,string where, string err)

Usage example:

    	
            
orderCache.Submit("Message", "(msgtype == 10)", ref exec_err);

Notice, that we use MsgType = 10, which stands for Order,

One can use MsgType = 14, to monitor Trade, to receive more specifics on Trade,

otherwise, Trades will still be received, as Update to Order. 

What Notifications To Expect From Order Monitoring 

Our included example REDIConsoleOrders implements REDI monitoring of orders for a small set of fields.

We see notifications such as:

    	
            

Add to Orders: Ref=gS046141282BranchCode=SR1BranchSeq=1|Symbol=IBM|Side=SELL|Quantity=100|ExecQuantity=0|PriceDesc=LMT 0.01|PctCmp=0.00%|Lvs=100|ExecPr=0|Account=RT00519803|Status=Open

Update to Order: Ref=gS046141282BranchCode=SR1BranchSeq=1|Symbol=IBM|Side=SELL|Quantity=100|ExecQuantity=100|PriceDesc=LMT 0.01|PctCmp=1 %|Lvs=0|ExecPr=141.21|Account=RT00519803|Status=Complete

Update to Order: Ref=gS046141282BranchCode=SR1BranchSeq=1|Symbol=IBM|Side=SELL|Quantity=100|ExecQuantity=150|PriceDesc=LMT 0.01|PctCmp=1.5 %|Lvs=0|ExecPr=94.1433|Account=RT00519803|Status=Complete

Add to Orders: Ref=gS046145282BranchCode=SR1BranchSeq=2|Symbol=IBM|Side=BUY|Quantity=777|ExecQuantity=700|PriceDesc=MKT|PctCmp=0.9009009009009009009009009009 %|Lvs=77|ExecPr=141.79|Account=RT00519803|Status=Partial

Update to Order: Ref=gS046145282BranchCode=SR1BranchSeq=2|Symbol=IBM|Side=BUY|Quantity=777|ExecQuantity=777|PriceDesc=MKT|PctCmp=1 %|Lvs=0|ExecPr=141.79|Account=RT00519803|Status=Complete

This is a typical output that shows a new order created, and then, its fields updated within REDI, without any action from the user.  The order has been executed, first, partially and next, fully.

Let us review more notifications:

    	
            

Add to Orders: Ref=gS046157282BranchCode=SR1BranchSeq=3|Symbol=BA|Side=BUY|Quantity=100|ExecQuantity=0|PriceDesc=LMT 0.01|PctCmp=0.00%|Lvs=100|ExecPr=0|Account=RT00519803|Status=Open

Update to Order: Ref=gS046157282BranchCode=SR1BranchSeq=3|Symbol=BA|Side=BUY|Quantity=100|ExecQuantity=0|PriceDesc=LMT 0.01|PctCmp=0.00%|Lvs=100|ExecPr=0|Account=RT00519803|Status=Pending Cancel

Update to Order: Ref=gS046157282BranchCode=SR1BranchSeq=3|Symbol=BA|Side=BUY|Quantity=100|ExecQuantity=0|PriceDesc=LMT 0.01|PctCmp=0.00%|Lvs=0|ExecPr=0|Account=RT00519803|Status=Canceled

This is a typical output of an order updated by an action affected by a user, a cancellation request is being received, and then the order status becomes canceled.

How To Monitor REDI Market Data

Definition:

AddWatch(int Type, string Symbol, string Account, string err)

Example of usage:

    	
            

if (isOption)                   

    quoteCache.AddWatch(WatchType.L1OPT, Symbol, null, ref err);

else // is an equity

    quoteCache.AddWatch(WatchType.L1, Symbol, null, ref err);

Notice that the type of instrument has to be supplied into the call

When we are not interested in market data on the instrument anymore, there comes the opposite call

Definition:

DeleteWatch(int Type, string Symbol, string Account, string err)

Usage example:

    	
            

if (isOption)

    quoteCache.DeleteWatch(WatchType.L1OPT, Symbol, null, ref err);

else

    quoteCache.DeleteWatch(WatchType.L1, Symbol, null, ref err);

In either case, an action has to be submitted:

Definition:

Submit(string table,string where, string err)

Usage example:

    	
            
quoteCache.Submit("L1", "", ref err);

What Notifications To Expect From Market Data Monitoring 

Our included example REDIConsoleL1 implements REDI monitoring of market data for equities and options.

We see notifications such as:

    	
            

Symbol=GOOG Action=Snapshot Bid=1213 Ask=1216.5 Last=1208.67 LastTradeSize= Volume=9136 ISIN=US02079K1079

Symbol=MSFT Action=Snapshot Bid=139.66 Ask=139.72 Last=139.7 LastTradeSize= Volume=183583 ISIN=US5949181045

Symbol=BA Action=Snapshot Bid=371.1 Ask=371.7 Last=371.48 LastTradeSize= Volume=27548 ISIN=US0970231058

Symbol=SPX   211217C03800000 Action=Add Bid=18.9 Ask=28.6 Last=23.8 LastTradeSize= Volume= ISIN=

Symbol=SPX   211217C03800000 Action=Add Bid=18.9 Ask=28.6 Last=23.8 LastTradeSize= Volume= ISIN=

Symbol=AAPL Action=Snapshot Bid=230.81 Ask=230.88 Last=230.09 LastTradeSize= Volume=286766 ISIN=US0378331005

Symbol=AAPL Action=Update Bid=230.81 Ask=230.88 Last=230.8101 LastTradeSize=3 Volume=286769 ISIN=US0378331005

Symbol=AAPL Action=Update Bid=230.81 Ask=230.88 Last=230.8101 LastTradeSize=3 Volume=286769 ISIN=US0378331005

Symbol=AAPL Action=Update Bid=230.81 Ask=230.88 Last=230.8101 LastTradeSize=3 Volume=286769 ISIN=US0378331005

Notice that: 

  •   Notifications are of type Snapshot, Update and Add.  
  •   For equities, we expect a Snapshot followed by Updates.
  •   For options, we expect Add followed by Updates.  
  •   Often, when the fields that we are watching did not change, however, there was an update, another field was updated, we would still get a notification for the update.

How To Monitor Positions

Definition:

AddWatch(int Type, string Symbol, string Account, string err)

Example of usage:

    	
            
positionCache.AddWatch("2", "", "MYACCOUNT", acct_err);

An action has to be submitted:

Definition:

Submit(string table, string where, string err)

Usage example:

    	
            
positionCache.Submit("Position", "true", ref pos_err);

Notice, we did not pass symbol into AddWatch, the parameter is passed empty.

What Notifications To Expect From Monitoring Positions 

Our included example REDIConsolePositions1 implements REDI monitoring of positions.

We see notifications such as:

    	
            

10/11/2019 3:12:41 PM>> PosCacheEve.action: (1) Snapshot

Row=0 Position: Symbol=IBM|Account=EQUITY-TR|Postion=55|Value=7909

Row=1 Position: Symbol=BA|Account=EQUITY-TR|Postion=333|Value=125322.0192

10/11/2019 3:12:41 PM>> PosCacheEve.action: (5) Update

Row=0: Account=EQUITY-TR DisplaySymbol=IBM Position=55 Value=7909

10/11/2019 3:12:41 PM>> PosCacheEve.action: (5) Update

Row=1: Account=EQUITY-TR DisplaySymbol=BA Position=333 Value=125322.0192

10/11/2019 3:12:42 PM>> PosCacheEve.action: (5) Update

Row=1: Account=EQUITY-TR DisplaySymbol=BA Position=333 Value=125311.23

10/11/2019 3:12:42 PM>> PosCacheEve.action: (5) Update

Row=0: Account=EQUITY-TR DisplaySymbol=IBM Position=55 Value=7909

We are looking for the complete view, of all positions the account holds.

A small set of positions is usually communicated within Snapshot.

A large set of current positions can be communicated on startup as Snapshot followed by 0 or more Adds.

Once all the current positions are communicated, we expect to see Updates.

An Update on a position can be triggered by a field change and also by change to the position being held.

A new position will result in an Add.

Also, when a new position is first created, we should see Updates from 0 to N to Position:

    	
            

Row=2: Account=EQUITY-TR DisplaySymbol=GOOG Position=0 Value=0

10/11/2019 3:14:29 PM>> PosCacheEve.action: (5) Update

Row=2: Account=EQUITY-TR DisplaySymbol=GOOG Position=500 Value=612560

10/11/2019 3:14:29 PM>> PosCacheEve.action: (5) Update

Row=2: Account=EQUITY-TR DisplaySymbol=GOOG Position=555 Value=679941.6

10/11/2019 3:14:30 PM>> PosCacheEve.action: (5) Update