/// <summary>
        /// Managed thread entrance only.
        /// </summary>
        void Managed_tdSink_ITradeDeskEvents_Event_OnRowChanged(object tableDisp, string rowID)
        {
            if (LoggedIn)
            {
                TradeDeskAut desk = _desk;
                if (desk == null)
                {
                    return;
                }

                try
                {
                    FXCore.ITableAut t = (FXCore.ITableAut)tableDisp;
                    if ("offers".Equals(t.Type))
                    {
                        TableAut offersTable   = (TableAut)desk.FindMainTable("offers");
                        RowAut   instrumentRow = (RowAut)offersTable.FindRow("OfferID", rowID, 0);

                        DataTick dataTick = new DataTick();
                        dataTick.Ask      = (decimal)((double)instrumentRow.CellValue("Ask"));
                        dataTick.Bid      = (decimal)((double)instrumentRow.CellValue("Bid"));
                        dataTick.DateTime = (DateTime)instrumentRow.CellValue("Time");

                        QuoteUpdateDelegate delegateInstance = QuoteUpdatedEvent;
                        if (delegateInstance != null)
                        {
                            GeneralHelper.FireAndForget(delegateInstance, this, (string)instrumentRow.CellValue("Instrument"), dataTick);
                        }
                    }
                    else if ("orders".Equals(t.Type))
                    {
                        // Orders table empty?
                        //TableAut offersTable = (TableAut)desk.FindMainTable("orders");
                        //RowAut instrumentRow = (RowAut)offersTable.FindRow("OrderID", rowID, 0);

                        //string accountId;
                        //OrderInfo? info = Managed_ExtractOrderInfo(instrumentRow, out accountId);

                        //OrderUpdateDelegate delegateInstance = OrderUpdatedEvent;
                        //if (info.HasValue && delegateInstance != null)
                        //{
                        //    GeneralHelper.FireAndForget(delegateInstance, this, accountId, info.Value);
                        //}
                    }
                    else if ("accounts".Equals(t.Type))
                    {
                        ItemUpdateDelegate delegateInstance = AccountUpdatedEvent;
                        if (delegateInstance != null)
                        {
                            GeneralHelper.FireAndForget(delegateInstance, this, rowID);
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    SystemMonitor.Error("Failed to handle OnRow event", ex);
                }
            }
        }
        /// <summary>
        ///
        /// </summary>
        public List <AccountInfo> GetAvailableAccounts(int advisedDecimalsPrecision)
        {
            List <AccountInfo> result = new List <AccountInfo>();

            TradeDeskAut desk = _desk;

            if (desk == null)
            {
                return(result);
            }

            GeneralHelper.DefaultDelegate delegateInstance = delegate()
            {
                try
                {
                    // Perform update.
                    TableAut accountsTable = (FXCore.TableAut)desk.FindMainTable("accounts");
                    foreach (RowAut item in (RowsEnumAut)accountsTable.Rows)
                    {
                        string id = (string)item.CellValue("AccountID");

                        if (string.IsNullOrEmpty(id))
                        {
                            SystemMonitor.OperationWarning("Account with null/empty id found.");
                            continue;
                        }

                        AccountInfo info = new AccountInfo();
                        // Have the accounts with default empty Guids.
                        //info.Guid = Guid.Empty;
                        info.Id = id;

                        info.Name       = "FXCM." + (string)item.CellValue("AccountName");
                        info.Balance    = Math.Round(new decimal((double)item.CellValue("Balance")), advisedDecimalsPrecision);
                        info.Equity     = Math.Round(new decimal((double)item.CellValue("Equity")), advisedDecimalsPrecision);
                        info.Margin     = Math.Round(new decimal((double)item.CellValue("UsableMargin")), advisedDecimalsPrecision);
                        info.Profit     = Math.Round(new decimal((double)item.CellValue("GrossPL")), advisedDecimalsPrecision);
                        info.FreeMargin = Math.Round(new decimal((double)item.CellValue("UsableMargin")), advisedDecimalsPrecision);
                        info.Company    = "FXCM";
                        info.Server     = this._serviceUrl;

                        result.Add(info);
                    }
                }
                catch (Exception ex)
                {
                    SystemMonitor.OperationError(GeneralHelper.GetExceptionMessage(ex));
                }
            };

            BackgroundMessageLoopOperator messageLoopOperator = _messageLoopOperator;

            if (messageLoopOperator != null)
            {
                messageLoopOperator.Invoke(delegateInstance, TimeSpan.FromSeconds(60));
            }

            return(result);
        }
        public object GetInstrumentData(string forexPair, string columnName)
        {
            object columnData = null;

            GeneralHelper.DefaultDelegate delegateInstance = delegate()
            {
                TradeDeskAut desk = _desk;
                if (desk == null)
                {
                    return;
                }

                FXCore.TableAut offersTable = (FXCore.TableAut)desk.FindMainTable("offers");
                if (offersTable == null)
                {
                    return;
                }

                switch (forexPair)
                {
                case "EUR/USD":
                    columnData = offersTable.CellValue(1, columnName);
                    break;

                case "USD/JPY":
                    columnData = offersTable.CellValue(2, columnName);
                    break;

                case "GBP/USD":
                    columnData = offersTable.CellValue(3, columnName);
                    break;

                case "USD/CHF":
                    columnData = offersTable.CellValue(4, columnName);
                    break;

                case "EUR/CHF":
                    columnData = offersTable.CellValue(5, columnName);
                    break;

                case "AUD/USD":
                    columnData = offersTable.CellValue(6, columnName);
                    break;

                case "USD/CAD":
                    columnData = offersTable.CellValue(7, columnName);
                    break;

                case "NZD/USD":
                    columnData = offersTable.CellValue(8, columnName);
                    break;

                case "EUR/GBP":
                    columnData = offersTable.CellValue(9, columnName);
                    break;

                case "EUR/JPY":
                    columnData = offersTable.CellValue(10, columnName);
                    break;

                case "GBP/JPY":
                    columnData = offersTable.CellValue(11, columnName);
                    break;

                case "GBP/CHF":
                    columnData = offersTable.CellValue(12, columnName);
                    break;
                }
            };

            BackgroundMessageLoopOperator messageLoopOperator = _messageLoopOperator;

            if (messageLoopOperator != null)
            {
                messageLoopOperator.Invoke(delegateInstance, TimeSpan.FromSeconds(60));
            }

            return(columnData);
        }
        List <PositionInfo> Managed_ProcessPositions()
        {
            List <PositionInfo> result = new List <PositionInfo>();

            TradeDeskAut desk = _desk;

            if (desk == null)
            {
                return(result);
            }

            TableAut tradesTable = (TableAut)desk.FindMainTable("summary");

            foreach (RowAut row in (RowsEnumAut)tradesTable.Rows)
            {
                // The unique number of the instrument that has open position(s).
                string offerID = (string)row.CellValue("OfferID");

                // The sequence number of the instrument in the list of instruments displayed to the Trading Station user.
                int defaultSortOrder = (int)row.CellValue("DefaultSortOrder");

                // The symbol indicating the instrument. For example, EUR/USD, USD/JPY, GBP/USD.
                string instrument = (string)row.CellValue("Instrument");

                // The current profit and loss on all positions opened in the instrument with the direction "sell". Commissions and interest are not taken into consideration. The SellNetP/L is expressed in the account currency.
                double sellNetPL = (double)row.CellValue("SellNetPL");

                // The trade amount of all positions opened in the instrument with the direction "sell".
                //The SellAmountK is expressed in the base currency of the instrument. For example, the value 50 for EUR/USD means that the total trade amount of all sell positions opened in EUR/USD is 50,000 Euros.
                double sellAmountK = (double)row.CellValue("SellAmountK");

                // The average open price of positions opened in the instrument with the direction "sell".
                double sellAverageOpen = (double)row.CellValue("SellAvgOpen");

                // The current market price at which all sell positions opened in the instrument can be closed.
                double buyClose = (double)row.CellValue("BuyClose");

                // The current market price at which all buy positions opened in the instrument can be closed.
                double sellClose = (double)row.CellValue("SellClose");

                // The average open price of positions opened in the instrument with the direction "buy".
                double buyAverageOpen = (double)row.CellValue("BuyAvgOpen");

                // The trade amount of all positions opened in the instrument with the direction "buy".
                //The BuyAmountK is expressed in the base currency of the instrument. For example, the value 50 for EUR/USD means that the total trade amount of all buy positions opened in EUR/USD is 50,000 Euros.
                double buyAmountK = (double)row.CellValue("BuyAmountK");

                // The current profit and loss on all positions opened in the instrument with the direction "buy". Commissions and interest are not taken into consideration. The BuyNetP/L is expressed in the account currency.
                double buyNetPL = (double)row.CellValue("BuyNetPL");

                // The trade amount of all positions (both buy and sell) opened in the instrument. The AmountK is expressed in the base currency of the instrument. For example, the value 50 for EUR/USD means that the total trade amount of all positions opened in EUR/USD is 50,000 Euros.
                double amountK = (double)row.CellValue("AmountK");

                // The current profit and loss on all positions (both buy and sell) opened in the instrument, including commissions and interest. The GrossPL is expressed in the account currency.
                double grossPL = (double)row.CellValue("GrossPL");

                // The current profit and loss on all positions (both buy and sell) opened in the instrument, without taking into consideration the commissions and interest. The NetPL is expressed in the account currency.
                double NetPL = (double)row.CellValue("NetPL");

                // Not currently available.
                // The current profit and loss (in pips) on all positions opened in the instrument with the direction "sell". Commissions and interest are not taken into consideration.
                //double sellNetPLPip = (double)row.CellValue("SellNetPLPip");

                // Not currently available.
                // The current profit and loss (in pips) on all positions opened in the instrument with the direction "buy". Commissions and interest are not taken into consideration.
                //double buyNetPLPip = (double)row.CellValue("BuyNetPLPip");

                PositionInfo info = new PositionInfo(new Symbol(Symbol.SymbolGroup.Forex, instrument), (decimal)(amountK * 1000),
                                                     (decimal)(buyAmountK > 0 ? Math.Round(buyNetPL, IntegrationAdapter.AdvisedAccountDecimalsPrecision) : Math.Round(sellNetPL, IntegrationAdapter.AdvisedAccountDecimalsPrecision)), null, null, null,
                                                     (decimal)(buyAmountK > 0 ? buyAverageOpen : sellAverageOpen), (decimal)(Math.Round(grossPL, IntegrationAdapter.AdvisedAccountDecimalsPrecision)), null, null);

                result.Add(info);
            }

            return(result);
        }