How to use table manager in ForexConnect API

Brief

The article describes the usage of a table manager in the ForexConnect API.

Details

A table manager creates and maintains the trading tables in the ForexConnect memory. The advantages of the table manager usage are described in the O2GTableManager class documentation.
The table manager implementation details are shown in the ForexConnect API Class Hierarchy section.
The following paragraphs contain complete instructions on the table manager usage.

Starting Table Manager

To ensure the correct usage of a table manager, you must follow these steps:

1. Create an O2GSession object by using the O2GTransport.createSession method. For example,

mSession = O2GTransport.createSession();


2. Before the login, specify that your session uses a table manager by calling the O2GSession.useTableManager method. For example,

mSession.useTableManager(O2GTableManagerMode.Yes, null);


3. Log on to the trading server by using the O2GSession.login method with your connection parameters. For example

mSession.login(mUserID, mPassword, mURL, mConnection);


Note: For complete login details, refer to the How to log in section.

4. Obtain an instance of the O2GTableManager class for your session by using the O2GSession.getTableManager method. For example,

O2GTableManager tableManager = mSession.getTableManager();


Note: An instance of the O2GTableManager class can be obtained only after a session gets the Connected status.
If the connection between the ForexConnect API and the trading server brakes, you may need to re-create an instance of the O2GTableManager class. In case of the restoration of the connection fails, the session status becomes Disconnected and you must log on again and create a new instance of the O2GTableManager class. If the ForexConnect API restores the connection successfully, you can use the existing instance of the O2GTableManager class. For a detailed explanation of the session statuses, refer to the Session Statuses section.

Getting Data from the Trading Tables

To get data from a trading table, you must follow these steps:

1. Check the table manager status.
An O2GTableManager object must have the O2GTableManagerStatus.TablesLoaded status.
For details on checking the table manager status, refer to the IO2GTableManagerListener documentation.

Note: You can also monitor the changes of the load status of every table in your implementation of the IO2GTableListener.onStatusChanged method. The table load status can be obtained at any time by calling the O2GTable.getStatus method. A table can be used only if it has the Refreshed status.

2. Use the O2GTableManager.getTable method to get an instance of one of the O2GTable subclasses and cast the return value to the corresponding subclass. The syntax examples for all trading tables are shown below:

Trading table

Returned O2GTable subclass

Syntax example

Offers

O2GOffersTable

O2GOffersTable offersTable = (O2GOffersTable)tableManager.getTable(O2GTableType.Offers);

Accounts

O2GAccountsTable

O2GAccountsTable accountsTable = (O2GAccountsTable)tableManager.getTable(O2GTableType.Accounts);

Orders

O2GOrdersTable

O2GOrdersTable ordersTable = (O2GOrdersTable)tableManager.getTable(O2GTableType.Orders);

Trades

O2GTradesTable

O2GTradesTable tradesTable = (O2GTradesTable)tableManager.getTable(O2GTableType.Trades);

Closed Trades

O2GClosedTradesTable

O2GClosedTradesTable closedTradesTable = (O2GClosedTradesTable)tableManager.getTable(O2GTableType.ClosedTrades);

Messages

O2GMessagesTable

O2GMessagesTable messagesTable = (O2GMessagesTable)tableManager.getTable(O2GTableType.Messages);

Summary

O2GSummaryTable

O2GSummaryTable summaryTable = (O2GSummaryTable)tableManager.getTable(O2GTableType.Summary);

3. Use one of the methods of the O2GTable subclass to get row level information. The methods are: findRow, getRow, getNextRow and getNextRowByColumnValue.
For example, if you want to get ask and bid prices from the Offers table, write the following lines:

Get bid and ask prices


for (int i = 0; i < offersTable.Count; i++)
{
    O2GOfferRow offer = offersTable.getRow(i);
    Console.WriteLine("Instrument: " + offer.Instrument +
                      " Bid = " + offer.Bid +
                      " Ask = " + offer.Ask);
}

For the methods definitions and code examples, refer to the documentation of the O2GTable subclasses shown in the table earlier.

Processing Notifications about the Trading Tables Updates

The trading tables are updated automatically. To process notifications about the trading tables updates, you must follow these steps:

1. Create a table listener class that implements the IO2GTableListener interface. For example,

public class TableListener implements IO2GTableListener {...}

2. Implement the methods of a table listener class:

- to process notifications about row additions to a table, implement the onAdded method;
- to process notifications about row changes of a table, implement the onChanged method;
- to process notifications about row deletions from a table,implement the onDeleted method.

3. Create an instance of a table listener class. For example,

TableListener tableListener = new TableListener();

4. Subscribe an instance of a table listener class to each update type individually by using the O2GTable.subscribeUpdate method.

5. Process notifications about table updates in the methods described in step 2 of this paragraph.

6. Before the logout, unsubscribe the listener from every subscribed update type separately by using the O2GTable.unsubscribeUpdate method.

For example, the table below shows the subscription/unsubsription syntax for the O2GTradesTable class and corresponding methods of a class implementing the IO2GTableListener interface.

Update type

IO2GTableListener method

Subscription syntax

Unsubscription syntax

Insert

onAdded

tradesTable.subscribeUpdate(O2GTableUpdateType.Insert, tableListener);
tradesTable.unsubscribeUpdate(O2GTableUpdateType.Insert, tableListener);

Update

onChanged

tradesTable.subscribeUpdate(O2GTableUpdateType.Update, tableListener);
tradesTable.unsubscribeUpdate(O2GTableUpdateType.Update, tableListener);

Delete

onDeleted

tradesTable.subscribeUpdate(O2GTableUpdateType.Delete, tableListener);
tradesTable.unsubscribeUpdate(O2GTableUpdateType.Delete, tableListener);

Using Table Manager Example

If you want to use a table manager to maintain information about opened positions, your program may look similar to the classes shown later:

MainController


class MainController
{
    private O2GSession mSession;
    private O2GTableManager mTblMgr;
    private string mRequestID;
 
    public void Run(string sUsername, string sPassword, string sUrl, string sConneciton)
    {
        mSession = O2GTransport.createSession();
        mSession.useTableManager(O2GTableManagerMode.Yes, null);
        SessionStatusListener statusListener = new SessionStatusListener();
        mSession.subscribeSessionStatus(statusListener);
        mSession.login(sUsername, sPassword, sUrl, sConneciton);
        while (statusListener.LastStatus != O2GSessionStatusCode.Connected && !statusListener.Failed)
            Thread.Sleep(50);
 
        mTblMgr = mSession.getTableManager();
 
        while (mTblMgr.getStatus() != O2GTableManagerStatus.TablesLoaded && mTblMgr.getStatus() != O2GTableManagerStatus.TablesLoadFailed)
        {
            Thread.Sleep(50);
        }
 
        O2GTradesTable trades = (O2GTradesTable)mTblMgr.getTable(O2GTableType.Trades);
        TradesListener listener = new TradesListener();
        trades.subscribeUpdate(O2GTableUpdateType.Insert, listener);
        trades.subscribeUpdate(O2GTableUpdateType.Update, listener);
        try
        {
            mTblMgr.lockUpdates();
            for (int ii = 0; ii < trades.Count; ii++)
            {
                O2GTradeTableRow trade = trades.getRow(ii);
                Console.WriteLine("TradeID={0}, OfferID={1}, Amount={2}", trade.TradeID, trade.OfferID, trade.Amount);
            }
        }
        finally
        {
            mTblMgr.unlockUpdates();
        }
 
        Thread.Sleep(10000); //waiting 10 sec for tracing new closed trades
 
        trades.unsubscribeUpdate(O2GTableUpdateType.Insert, listener);
        trades.unsubscribeUpdate(O2GTableUpdateType.Update, listener);
 
        mSession.logout();
        while (statusListener.LastStatus != O2GSessionStatusCode.Disconnected && !statusListener.Failed)
            Thread.Sleep(50);
        mSession.unsubscribeSessionStatus(statusListener);
        mSession.Dispose();
        mSession = null;
    }
}

SessionStatusListener


class SessionStatusListener:IO2GSessionStatus
{
    private object mSyncObj = new Object();
 
    public O2GSessionStatusCode LastStatus
    {
        get
        {
            lock(mSyncObj)
                return mLastStatus;
        }
        set
        {
            lock(mSyncObj)
                mLastStatus = value;
        }
    }
    private O2GSessionStatusCode mLastStatus = O2GSessionStatusCode.Unknown;
 
    public bool Failed
    {
        get { return mFailed; }
    }
    private volatile bool mFailed = false;
 
    public string LastError
    {
        get { return mLastError; }
    }
    private string mLastError =string.Empty;
 
    #region IO2GSessionStatus Members
 
    public void onLoginFailed(string error)
    {
        mFailed = true;
        mLastError = error;
    }
 
    public void onSessionStatusChanged(O2GSessionStatusCode status)
    {
        LastStatus = status;
        mFailed = false;
        mLastError = string.Empty;
    }
 
    #endregion
}

TradesListener.java


class TradesListener : IO2GTableListener
{
    public void onAdded(string rowID, O2GRow rowData)
    {
        O2GTradeTableRow trade = (O2GTradeTableRow)rowData;
        Console.WriteLine("Added TradeID={0}, OfferID={1}, Amount={2}", trade.TradeID, trade.OfferID, trade.Amount);
    }
 
    public void onChanged(string rowID, O2GRow rowData)
    {
        O2GTradeTableRow trade = (O2GTradeTableRow)rowData;
        Console.WriteLine("Changed TradeID={0}, OfferID={1}, Amount={2}", trade.TradeID, trade.OfferID, trade.Amount);
    }
 
    public void onDeleted(string rowID, O2GRow rowData)
    {
 
    }
 
    public void onStatusChanged(O2GTableStatus status)
    {
 
    }
}

back