/// <summary>
        /// Decode price FIX message
        /// </summary>
        /// <param name="FIXMsg"></param>
        /// <returns></returns>
        public bool DecodeFIXMessage(IFIXMessage FIXMsg)
        {
            try
            {
                IFIXGroup fixCountGroup = FIXMsg.GetGroupByTag(FIXTagConstants.esFIXTagESNoSecurityPositions, null);
                if (fixCountGroup != null)
                {
                    for (int i = 0; i < fixCountGroup.get_NumberOfGroups(null); i++)
                    {
                        IFIXGroup fixRptGroup = fixCountGroup.GetGroupByIndex(i);

                        string strMnemonic = fixRptGroup.get_AsString(FIXTagConstants.esFIXTagESTickerMnemonic);
                        string strSecExchange = fixRptGroup.get_AsString(FIXTagConstants.esFIXTagSecurityExchange);
                        string strContractGroup = fixRptGroup.get_AsString(FIXTagConstants.esFIXTagESContractGroup);
                        string strContractGroupOffset = fixRptGroup.get_AsString(FIXTagConstants.esFIXTagESMarginGroupOffset);
                        Position thePosition;
                        if (m_Positions.ContainsKey(strMnemonic))
                            thePosition = m_Positions[strMnemonic];
                        else
                        {
                            thePosition = new Position(m_iAccountID);
                            thePosition.Symbol = strMnemonic;
                            m_Positions.Add(strMnemonic, thePosition);
                        }
                        thePosition.DecodeFIXGroup(fixRptGroup);
                    }
                }
                IFIXGroup group = FIXMsg.GetGroupByTag(FIXTagConstants.esFIXTagESNoSecurityExchanges, null);

                if (group != null)
                {
                    int nCount = group.get_NumberOfGroups(null);

                    for (int i = 0; i < nCount; i++)
                    {
                        IFIXGroup singleGroup = group.GetGroupByIndex(i);

                        string sExchange = singleGroup.get_AsString(FIXTagConstants.esFIXTagSecurityExchange);

                        AddTicker(sExchange, singleGroup);
                    }
                }

                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        public bool DecodeRiskAccountFIXMessage(IFIXMessage FIXMsg)
        {
            m_strAccountName = FIXMsg.get_AsString(FIXTagConstants.esFIXTagESAccountName);
            m_strAccountCode = FIXMsg.get_AsString(FIXTagConstants.esFIXTagESAccountCode);
            m_strDescription = FIXMsg.get_AsString(FIXTagConstants.esFIXTagESAccountDesc);
            m_strCurrency = FIXMsg.get_AsString(FIXTagConstants.esFIXTagESAccountCurrency);

                   /* If .GetDouble(dblValue, esFIXTagESAllowableMarginCredit) Then m_udtAccountCache(aCOL_ALLOWABLE_MARGIN_CREDIT, lngRow).vntValue = dblValue
                    If .GetDouble(dblValue, esFIXTagESGrossLiquidity) Then m_udtAccountCache(aCOL_GROSS_LIQUIDITY, lngRow).vntValue = dblValue
                    If .GetDouble(dblValue, esFIXTagESMarginFactor) Then m_udtAccountCache(aCOL_MARGIN_FACTOR, lngRow).vntValue = dblValue

                    If .GetNumber(lngValue, esFIXTagESAccountStatus) Then m_udtAccountCache(aCOL_ACCOUNT_ACTIVE, lngRow).vntValue = GetRiskAccountStatusDesc(lngValue)
                    If .GetNumber(lngValue, esFIXTagESRiskPermissioningLevel) Then m_udtAccountCache(aCOL_RISK_PERMISSIONING_LEVEL, lngRow).vntValue = GetRiskPermissioningLevelDesc(lngValue)
                    m_udtAccountCache(aCOL_ACCOUNT_ACTIVE, lngRow).lngValidityStatus = esESStatusSeverityInfo
                    m_udtAccountCache(aCOL_RISK_PERMISSIONING_LEVEL, lngRow).lngValidityStatus = esESStatusSeverityInfo
               */
            return true;
        }
        /// <summary>
        /// Process Tradable Entity Instrument FIX Update message
        /// </summary>
        /// <param name="FIXMsg"></param>
        /// <returns></returns>
        public TEInstrument HandleTEInstrumentUpdate(IFIXMessage FIXMsg)
        {
            TEInstrument instrument = null;
            string sType = FIXMsg.get_AsString(FIXTagConstants.esFIXTagSecurityResponseType);

            if (sType == MESSAGEFIX3Lib.FIXSecurityResponseTypeConstants.esFIXSecurityResponseTypeReturnSecurities)
            {
                //BeginString=FIX.4.2|BodyLength=118|
                //MsgType=SecurityDef<d>|SecurityResponseType=SecurityResponseTypeReturnSecurities<4>
                //|SecurityExchange=3|ESExchange=F|Symbol=USD|SecurityType=FOR|ESTickerDesc=USD-CAD|
                //ESTickerSymbol=USD-CAD|ESTimeType=TimeTypeImmediateAndCancel<0x00000002>
                //|ESOrderType=OrderTypeLimit<0x00000006>|ESSupportEdit=0|
                //ESPriceFormatCode=0|ESTickerMnemonic=3FX:USD-CAD|CheckSum=056|

                string sExchange = FIXMsg.get_AsString(EASYROUTERCOMCLIENTLib.FIXTagConstants.esFIXTagSecurityExchange);
                string sESExchange = FIXMsg.get_AsString(EASYROUTERCOMCLIENTLib.FIXTagConstants.esFIXTagESExchange);
                string sSecurityType = FIXMsg.get_AsString(EASYROUTERCOMCLIENTLib.FIXTagConstants.esFIXTagSecurityType);
                string sSymbol = FIXMsg.get_AsString(EASYROUTERCOMCLIENTLib.FIXTagConstants.esFIXTagSymbol);
                string sESTickerMnemonic = FIXMsg.get_AsString(EASYROUTERCOMCLIENTLib.FIXTagConstants.esFIXTagESTickerMnemonic);

                SecurityExchange exchange = GetExchange(sExchange);
                //have the top level exchange SECURITY EXCHAANGE eg EUREX VALUES V
                if (exchange != null)
                {
                    //have the esxchange ESEXCHANGE eg V
                    ESExchange esexchange = exchange.GetESExchange(sESExchange);
                    if (esexchange == null)
                        esexchange = exchange.AddESExchange(sESExchange, "Unknown");

                    //find the security type eg OPT
                    Commodity commodity = esexchange.GetCommodity(sSecurityType);

                    CommoditySymbol commoditysymbol = null;
                    //test if we have commodity else create the commodity + commodity symbol objects
                    if (commodity == null)
                    {
                        commoditysymbol = esexchange.AddCommodity(sSecurityType, sSymbol, "Unknown");
                    }
                    else
                    {
                        //find commodity if exists ESCONTRACT eg SIE
                        commoditysymbol = commodity.AddCommoditySymbol(sSymbol, "Unknown");
                    }
                    //see if we have this TE already VVO:SIE Mar 07 7000c O
                    instrument = commoditysymbol.AddTEInstrument(sESTickerMnemonic, FIXMsg);
                    //add to direct map
                    if (instrument != null)
                    {
                        AddDirectTE(instrument);

                        if (instrument.m_sMDExchange.Length > 0 & instrument.m_sSecurityID.Length > 0)
                        {
                            string sTempSymbol = instrument.m_sSecurityID + instrument.m_sMDExchange;
                            if (!m_directISINMap.ContainsKey(sTempSymbol))
                                m_directISINMap[sTempSymbol] = instrument;
                        }
                    }
                }
            }
            return instrument;
        }
        /// <summary>
        /// Process Security FIX Update message
        /// </summary>
        /// <param name="FIXMsg"></param>
        /// <returns></returns>
        public SecurityExchange HandleSecurityUpdate(IFIXMessage FIXMsg)
        {
            SecurityExchange exchange = null;
            string sType = FIXMsg.get_AsString(FIXTagConstants.esFIXTagSecurityResponseType);

            if (sType == MESSAGEFIX3Lib.FIXSecurityResponseTypeConstants.esFIXSecurityResponseTypeReturnSecurityExchanges) //Exchange
            {
                //BeginString=FIX.4.2|BodyLength=29|MsgType=SecurityDef<d>|
                //SecurityResponseType=SecurityResponseTypeReturnSecurityExchanges<U>|
                //SecurityExchange=3|ESSecurityExchangeDesc=FOREX|CheckSum=220|10=250:<end>

                string sExchange = FIXMsg.get_AsString(FIXTagConstants.esFIXTagSecurityExchange);
                string sExchangeDesc = FIXMsg.get_AsString(FIXTagConstants.esFIXTagESSecurityExchangeDesc);

                //Add exchange if does not exist
                exchange = AddExchange(sExchange, sExchangeDesc);
            }
            return exchange;
        }
        /// <summary>
        /// Process ESExchange FIX Update message
        /// </summary>
        /// <param name="FIXMsg"></param>
        /// <returns></returns>
        public ESExchange HandleESExchangeUpdate(IFIXMessage FIXMsg)
        {
            ESExchange esExchange = null;
            string sType = FIXMsg.get_AsString(FIXTagConstants.esFIXTagSecurityResponseType);

            if (sType == MESSAGEFIX3Lib.FIXSecurityResponseTypeConstants.esFIXSecurityResponseTypeReturnESExchanges)
            {
                string sExchange = FIXMsg.get_AsString(FIXTagConstants.esFIXTagSecurityExchange);
                string sESExchange = FIXMsg.get_AsString(FIXTagConstants.esFIXTagESExchange);
                string sExchangeDesc = FIXMsg.get_AsString(FIXTagConstants.esFIXTagESExchangeDesc);
            #if DEBUG
                System.Diagnostics.Debug.WriteLine("SEC DEF V EXCHANGE = " + sExchange + " ESEXCHANGE = " + sESExchange);
            #endif
                SecurityExchange exchange = GetExchange(sExchange);

                esExchange = exchange.AddESExchange(sESExchange, sExchangeDesc);

            }
            return esExchange;
        }
        /// <summary>
        /// Process Commodity FIX Update message
        /// </summary>
        /// <param name="FIXMsg"></param>
        /// <returns></returns>
        public CommoditySymbol HandleCommodityUpdate(IFIXMessage FIXMsg)
        {
            CommoditySymbol commoditysymbol = null;

            string sType = FIXMsg.get_AsString(FIXTagConstants.esFIXTagSecurityResponseType);

            if (sType == MESSAGEFIX3Lib.FIXSecurityResponseTypeConstants.esFIXSecurityResponseTypeReturnSymbols)
            {
                //BeginString=FIX.4.2|BodyLength=48|MsgType=SecurityDef<d>|
                //SecurityResponseType=SecurityResponseTypeReturnSymbols<W>|
                //SecurityExchange=3|ESExchange=F|Symbol=EUR|SecurityDesc=EUR|
                //SecurityType=FOR|CheckSum=038||10=038|'

                string sExchange = FIXMsg.get_AsString(EASYROUTERCOMCLIENTLib.FIXTagConstants.esFIXTagSecurityExchange);
                string sESExchange = FIXMsg.get_AsString(EASYROUTERCOMCLIENTLib.FIXTagConstants.esFIXTagESExchange);
                string sSymbol = FIXMsg.get_AsString(EASYROUTERCOMCLIENTLib.FIXTagConstants.esFIXTagSymbol);
                string sSecurityType = FIXMsg.get_AsString(EASYROUTERCOMCLIENTLib.FIXTagConstants.esFIXTagSecurityType);
                string sSecurityDesc = FIXMsg.get_AsString(EASYROUTERCOMCLIENTLib.FIXTagConstants.esFIXTagSecurityDesc);

                SecurityExchange exchange = GetExchange(sExchange);
                if (exchange != null)
                {
                    ESExchange esexchange = exchange.GetESExchange(sESExchange);
                    if (esexchange != null)
                    {
                        commoditysymbol = esexchange.AddCommodity(sSecurityType, sSymbol, sSecurityDesc);
                    }
                }
            }
            return commoditysymbol;
        }
        /// <summary>
        /// Decode price FIX message
        /// </summary>
        /// <param name="FIXMsg"></param>
        /// <param name="bSnapFull"></param>
        /// <returns></returns>
        public bool DecodeFIX(IFIXMessage FIXMsg,bool bSnapFull)
        {
            bool bReturn = false;
            m_sSymbol = FIXMsg.get_AsString(FIXTagConstants.esFIXTagESTickerMnemonic);

            int nTotal = 0;
            if (FIXMsg.GetNumber(out nTotal, FIXTagConstants.esFIXTagTotalVolumeTraded))
                m_nTotalTradeVolume = nTotal;

            IFIXGroup group = FIXMsg.GetGroupByTag(FIXTagConstants.esFIXTagNoMDEntries, null);

            if (group != null)
            {
                int nCount = group.get_NumberOfGroups(null);

                for (int i = 0; i < nCount; i++)
                {
                    IFIXGroup singleGroup = group.GetGroupByIndex(i);

                    string sType = singleGroup.get_AsString(FIXTagConstants.esFIXTagMDEntryType);

                    int nImplied = singleGroup.get_AsNumber(FIXTagConstants.esFIXTagESMDEntryIsImplied);
                    string sTime = singleGroup.get_AsString(FIXTagConstants.esFIXTagMDEntryTime);

                    bReturn = true;

                    switch (sType)
                    {
                        case MESSAGEFIX3Lib.FIXMarketDataTypeConstants.esFIXMarketDataTypeBestAsk:
                            {
                                switch (nImplied)
                                {
                                    case (int)MESSAGEFIX3Lib.FIXESIsImpliedConstants.esFIXESIsImpliedBestFromActual:
                                    case (int)MESSAGEFIX3Lib.FIXESIsImpliedConstants.esFIXESIsImpliedBestFromActualAndImplied:
                                    case (int)MESSAGEFIX3Lib.FIXESIsImpliedConstants.esFIXESIsImpliedBestFromImplied:
                                    case (int)MESSAGEFIX3Lib.FIXESIsImpliedConstants.esFIXESIsImpliedBestImpliedNoActual:
                                        m_eAskOrderType = (Implied)nImplied;
                                        SetPrice(out m_Ask, singleGroup);
                                        break;
                                }
                                break;
                            }
                        case MESSAGEFIX3Lib.FIXMarketDataTypeConstants.esFIXMarketDataTypeBestBid:
                            {
                                switch (nImplied)
                                {
                                    case (int)MESSAGEFIX3Lib.FIXESIsImpliedConstants.esFIXESIsImpliedBestFromActual:
                                    case (int)MESSAGEFIX3Lib.FIXESIsImpliedConstants.esFIXESIsImpliedBestFromActualAndImplied:
                                    case (int)MESSAGEFIX3Lib.FIXESIsImpliedConstants.esFIXESIsImpliedBestFromImplied:
                                    case (int)MESSAGEFIX3Lib.FIXESIsImpliedConstants.esFIXESIsImpliedBestImpliedNoActual:
                                        m_eBidOrderType = (Implied)nImplied;
                                        SetPrice(out m_Bid, singleGroup);
                                        break;
                                }
                                break;
                                break;
                            }

                        case MESSAGEFIX3Lib.FIXMarketDataTypeConstants.esFIXMarketDataTypeSettlementPrice:
                            {
                                int nType = singleGroup.get_AsNumber(FIXTagConstants.esFIXTagOpenCloseSettlementFlag);

                                MESSAGEFIX3Lib.FIXSettlementFlagConstants type = (MESSAGEFIX3Lib.FIXSettlementFlagConstants)nType;

                                double dPrice = singleGroup.get_AsDouble(FIXTagConstants.esFIXTagMDEntryPx);
                                if (type == MESSAGEFIX3Lib.FIXSettlementFlagConstants.esFIXSettlementOpenCloseYesterday)
                                {
                                    m_dSettlement = dPrice;
                                    m_sSettlementTime = singleGroup.get_AsString(FIXTagConstants.esFIXTagMDEntryTime);
                                    m_sSettlementDate = singleGroup.get_AsString(FIXTagConstants.esFIXTagMDEntryDate);
                                }
                                else
                                {
                                    m_dPrevSettlement = dPrice;
                                    m_sPrevSettlementTime = singleGroup.get_AsString(FIXTagConstants.esFIXTagMDEntryTime);
                                    m_sPrevSettlementDate = singleGroup.get_AsString(FIXTagConstants.esFIXTagMDEntryDate);
                                }
                                break;
                            }
                        case MESSAGEFIX3Lib.FIXMarketDataTypeConstants.esFIXMarketDataTypeClosingPrice:
                            {
                                m_dClose = singleGroup.get_AsDouble(FIXTagConstants.esFIXTagMDEntryPx);
                                break;
                            }
                        case MESSAGEFIX3Lib.FIXMarketDataTypeConstants.esFIXMarketDataTypeTrade:
                            {
                                SetPrice(out m_Trade, singleGroup);
                                break;
                            }
                        case MESSAGEFIX3Lib.FIXMarketDataTypeConstants.esFIXMarketDataTypeSessionHighPrice:
                            {
                                m_SessionHigh = singleGroup.get_AsDouble(FIXTagConstants.esFIXTagMDEntryPx);
                                break;
                            }
                        case MESSAGEFIX3Lib.FIXMarketDataTypeConstants.esFIXMarketDataTypeSessionLowPrice:
                            {
                                m_SessionLow = singleGroup.get_AsDouble(FIXTagConstants.esFIXTagMDEntryPx);
                                break;
                            }
                    }
                }
            }
            m_bSnapshot = bSnapFull;
            return bReturn;
        }