Classes Files

cs/MamdaOrderImbalanceListener.cs

Namespaces

Name
Wombat

Classes

  Name
class Wombat::MamdaOrderImbalanceListener
A MamdaOrderImbalanceListener is class that specializes in handling imbalance order updates. An imbalance order occurs when too many orders of a particular type - either buy, sell or limit - for listed securities and not enough of the other, matching orders are received by an exchange. Developers provide their own implementation of the MamdaOrderImbalanceHandler interface and will be delivered notifications for imbalance updates.

Source code

/* $Id$
 *
 * OpenMAMA: The open middleware agnostic messaging API
 * Copyright (C) 2011 NYSE Technologies, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */

using System;
using System.Collections;
using System.Threading;

namespace Wombat
{
    public class MamdaOrderImbalanceListener :
        MamdaMsgListener,
        MamdaBasicEvent,
        MamdaBasicRecap,
        MamdaOrderImbalanceRecap
    {
        public MamdaOrderImbalanceListener()
        {
            clearCache (mOrderImbalanceCache);

            mFieldIterator = new FieldIterator(this);
        }

        public void addHandler(MamdaOrderImbalanceHandler handler)
        {
            mHandlers.Add(handler);
        }

        public  MamaPrice getHighIndicationPrice()
        {
            return mOrderImbalanceCache.mHighIndicationPrice;
        }

        public  MamaPrice getLowIndicationPrice()
        {
            return mOrderImbalanceCache.mLowIndicationPrice;
        }

        public  MamaPrice getImbalancePrice()
        {
            return mOrderImbalanceCache.mIndicationPrice;
        }

        public  long getBuyVolume ()
        {
            return mOrderImbalanceCache.mBuyVolume;
        }

        public  long getSellVolume ()
        {
            return mOrderImbalanceCache.mSellVolume;
        }

        public  long getMatchVolume ()
        {
            return mOrderImbalanceCache.mMatchVolume;
        }

        public  String getImbalanceState ()
        {
            return mOrderImbalanceCache.mSecurityStatusQual;
        }

        public  MamaPrice getMatchPrice ()
        {
            return mOrderImbalanceCache.mInsideMatchPrice;
        }

        public  MamaPrice getFarClearingPrice ()
        {
            return mOrderImbalanceCache.mFarClearingPrice;
        }

        public  MamaPrice getNearClearingPrice ()
        {
            return mOrderImbalanceCache.mNearClearingPrice;
        }

        public  char getNoClearingPrice ()
        {
            return mOrderImbalanceCache.mNoClearingPrice;
        }

        public  char getPriceVarInd ()
        {
            return mOrderImbalanceCache.mPriceVarInd;
        }

        public  char getCrossType ()
        {
            return mOrderImbalanceCache.mCrossType;
        }

        public  DateTime getEventTime ()
        {
            return mOrderImbalanceCache.mEventTime;
        }

        public long getEventSeqNum ()
        {
            return mOrderImbalanceCache.mEventSeqNum;
        }

        public DateTime getActivityTime ()
        {
            return mOrderImbalanceCache.mActTime;
        }

        public DateTime getSrcTime ()
        {
            return mOrderImbalanceCache.mSrcTime;
        }

        public DateTime getLineTime ()
        {
            return mOrderImbalanceCache.mLineTime;
        }

        public DateTime getSendTime ()
        {
            return mOrderImbalanceCache.mSendTime;
        }

        public int getMsgType ()
        {
            return mOrderImbalanceCache.mMsgType;
        }

        public String getIssueSymbol ()
        {
            return mOrderImbalanceCache.mIssueSymbol;
        }

        public String getSymbol ()
        {
            return mOrderImbalanceCache.mSymbol;
        }

        public String getPartId ()
        {
            return mOrderImbalanceCache.mPartId;
        }

        public int getSeqNum ()
        {
            return mOrderImbalanceCache.mSeqNum;
        }

        public String getSecurityStatusOrig ()
        {
            return mOrderImbalanceCache.mSecurityStatusOrig;
        }

        public DateTime getSecurityStatusTime ()
        {
            return mOrderImbalanceCache.mSecurityStatusTime;
        }

        public DateTime getAuctionTime ()
        {
            return mOrderImbalanceCache.mAuctionTime;
        }

/*      FieldState Accessors        */

        public  MamdaFieldState getHighIndicationPriceFieldState()
        {
            return mOrderImbalanceCache.mHighIndicationPriceFieldState;
        }

        public  MamdaFieldState getLowIndicationPriceFieldState()
        {
            return mOrderImbalanceCache.mLowIndicationPriceFieldState;
        }

        public  MamdaFieldState getImbalancePriceFieldState()
        {
            return mOrderImbalanceCache.mIndicationPriceFieldState;
        }

        public  MamdaFieldState getBuyVolumeFieldState()
        {
            return mOrderImbalanceCache.mBuyVolumeFieldState;
        }

        public  MamdaFieldState getSellVolumeFieldState()
        {
            return mOrderImbalanceCache.mSellVolumeFieldState;
        }

        public  MamdaFieldState getMatchVolumeFieldState()
        {
            return mOrderImbalanceCache.mMatchVolumeFieldState;
        }

        public  MamdaFieldState getImbalanceStateFieldState()
        {
            return mOrderImbalanceCache.mSecurityStatusQualFieldState;
        }

        public  MamdaFieldState getMatchPriceFieldState()
        {
            return mOrderImbalanceCache.mInsideMatchPriceFieldState;
        }

        public  MamdaFieldState getFarClearingPriceFieldState()
        {
            return mOrderImbalanceCache.mFarClearingPriceFieldState;
        }

        public  MamdaFieldState getNearClearingPriceFieldState()
        {
            return mOrderImbalanceCache.mNearClearingPriceFieldState;
        }

        public  MamdaFieldState getNoClearingPriceFieldState()
        {
            return mOrderImbalanceCache.mNoClearingPriceFieldState;
        }

        public  MamdaFieldState getPriceVarIndFieldState()
        {
            return mOrderImbalanceCache.mPriceVarIndFieldState;
        }

        public  MamdaFieldState getCrossTypeFieldState()
        {
            return mOrderImbalanceCache.mCrossTypeFieldState;
        }

        public  MamdaFieldState getEventTimeFieldState()
        {
            return mOrderImbalanceCache.mEventTimeFieldState;
        }

        public MamdaFieldState getEventSeqNumFieldState()
        {
            return mOrderImbalanceCache.mEventSeqNumFieldState;
        }

        public MamdaFieldState getActivityTimeFieldState()
        {
            return mOrderImbalanceCache.mActTimeFieldState;
        }

        public MamdaFieldState getSrcTimeFieldState()
        {
            return mOrderImbalanceCache.mSrcTimeFieldState;
        }

        public MamdaFieldState getLineTimeFieldState()
        {
            return mOrderImbalanceCache.mLineTimeFieldState;
        }

        public MamdaFieldState getSendTimeFieldState()
        {
            return mOrderImbalanceCache.mSendTimeFieldState;
        }

        public MamdaFieldState getMsgTypeFieldState()
        {
            return mOrderImbalanceCache.mMsgTypeFieldState;
        }

        public MamdaFieldState getIssueSymbolFieldState()
        {
            return mOrderImbalanceCache.mIssueSymbolFieldState;
        }

        public MamdaFieldState getSymbolFieldState()
        {
            return mOrderImbalanceCache.mSymbolFieldState;
        }

        public MamdaFieldState getPartIdFieldState()
        {
            return mOrderImbalanceCache.mPartIdFieldState;
        }

        public MamdaFieldState getSeqNumFieldState()
        {
            return mOrderImbalanceCache.mSeqNumFieldState;
        }

        public MamdaFieldState getSecurityStatusOrigFieldState()
        {
            return mOrderImbalanceCache.mSecurityStatusOrigFieldState;
        }

        public MamdaFieldState getSecurityStatusTimeFieldState()
        {
            return mOrderImbalanceCache.mSecurityStatusTimeFieldState;
        }

        public MamdaFieldState getAuctionTimeFieldState()
        {
            return mOrderImbalanceCache.mAuctionTimeFieldState;
        }

/*      End FieldState Accessors        */

        public void  populateRecap(MamdaConcreteOrderImbalanceRecap recap)
        {
            lock (this)
            {
                recap.clear();
                recap.setHighIndicationPrice (mOrderImbalanceCache.mHighIndicationPrice);
                recap.setLowIndicationPrice  (mOrderImbalanceCache.mLowIndicationPrice);
                recap.setImbalancePrice      (mOrderImbalanceCache.mIndicationPrice);
                recap.setBuyVolume           (mOrderImbalanceCache.mBuyVolume);
                recap.setSellVolume          (mOrderImbalanceCache.mSellVolume);
                recap.setMatchVolume         (mOrderImbalanceCache.mMatchVolume);
                recap.setImbalanceState      (mOrderImbalanceCache.mSecurityStatusQual);
                recap.setMatchPrice          (mOrderImbalanceCache.mInsideMatchPrice);
                recap.setFarClearingPrice    (mOrderImbalanceCache.mFarClearingPrice);
                recap.setNearClearingPrice   (mOrderImbalanceCache.mNearClearingPrice);
                recap.setNoClearingPrice     (mOrderImbalanceCache.mNoClearingPrice);
                recap.setPriceVarInd         (mOrderImbalanceCache.mPriceVarInd);
                recap.setCrossType           (mOrderImbalanceCache.mCrossType);
                recap.setEventTime           (mOrderImbalanceCache.mEventTime);
                recap.setEventSeqNum         (mOrderImbalanceCache.mEventSeqNum);
                recap.setMsgType             (mOrderImbalanceCache.mMsgType);
                recap.setIssueSymbol         (mOrderImbalanceCache.mIssueSymbol);
                recap.setPartId              (mOrderImbalanceCache.mPartId);
                recap.setSeqNum              (mOrderImbalanceCache.mSeqNum);
                recap.setSecurityStatusOrig  (mOrderImbalanceCache.mSecurityStatusOrig);
                recap.setSecurityStatusTime  (mOrderImbalanceCache.mSecurityStatusTime);
                recap.setAuctionTime         (mOrderImbalanceCache.mAuctionTime);
                recap.setSrcTime             (mOrderImbalanceCache.mSrcTime);
                recap.setActivityTime        (mOrderImbalanceCache.mActTime);
                recap.setSymbol              (mOrderImbalanceCache.mSymbol);
                recap.setLineTime            (mOrderImbalanceCache.mLineTime);
                recap.setSendTime            (mOrderImbalanceCache.mSendTime);
            }
        }

        public MamdaOrderImbalanceSide getImbalanceSide ()
        {
            if (mOrderImbalanceCache.mBuyVolume >
                mOrderImbalanceCache.mSellVolume)
            {
                mSide = MamdaOrderImbalanceSide.BID_SIDE;
            }
            else
            {
                mSide = MamdaOrderImbalanceSide.ASK_SIDE;
            }
            return mSide;
        }

        public long getImbalanceVolume ()
        {
            if (MamdaOrderImbalanceSide.BID_SIDE == getImbalanceSide())
            {
                return (getBuyVolume () - getSellVolume());
            }
            return (getSellVolume () - getBuyVolume());
        }

        public void onMsg(
            MamdaSubscription   subscription,
            MamaMsg             msg,
            mamaMsgType         msgType)
        {
            if (mUpdaters == null)
            {
                lock (mUpdatersGuard)
                {
                    if(!MamdaOrderImbalanceFields.isSet())
                    {
                        return;
                    }

                    if (mUpdaters == null)
                    {
                        ImbalanceOrderUpdate[] updaters = createUpdaters();
                        Thread.MemoryBarrier();
                        mUpdaters = updaters;
                    }
                }
            }

            switch (msgType)
            {
                case mamaMsgType.MAMA_MSG_TYPE_INITIAL:
                case mamaMsgType.MAMA_MSG_TYPE_RECAP:
                case mamaMsgType.MAMA_MSG_TYPE_UPDATE:
                    updateFieldStates();
                    updateOrderImbalanceFields(subscription, msg, msgType);
                    break;
                default:
                    break;
            }
        }

        #region Implementation details

        private void handleRecap(
            MamdaSubscription   subscription,
            MamaMsg             msg)
        {
            foreach (MamdaOrderImbalanceHandler handler in mHandlers)
            {
                handler.onOrderImbalanceRecap(subscription, this, msg);
            }
        }

        private void handleOrderImbalance(
            MamdaSubscription   subscription,
            MamaMsg             msg)
        {
            foreach (MamdaOrderImbalanceHandler handler in mHandlers)
            {
                handler.onOrderImbalance(subscription, this, msg);
            }
        }

        private void handleNoOrderImbalance(
            MamdaSubscription   subscription,
            MamaMsg             msg)
        {
            foreach (MamdaOrderImbalanceHandler handler in mHandlers)
            {
                handler.onNoOrderImbalance(subscription, this, msg);
            }
        }

        private void updateFieldStates()
        {
        if (mOrderImbalanceCache.mHighIndicationPriceFieldState == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mHighIndicationPriceFieldState = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mLowIndicationPriceFieldState  == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mLowIndicationPriceFieldState  = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mIndicationPriceFieldState     == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mIndicationPriceFieldState     = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mBuyVolumeFieldState           == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mBuyVolumeFieldState           = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mSellVolumeFieldState          == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mSellVolumeFieldState          = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mMatchVolumeFieldState         == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mMatchVolumeFieldState         = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mSecurityStatusQualFieldState  == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mSecurityStatusQualFieldState  = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mInsideMatchPriceFieldState    == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mInsideMatchPriceFieldState    = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mFarClearingPriceFieldState    == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mFarClearingPriceFieldState    = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mNearClearingPriceFieldState   == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mNearClearingPriceFieldState   = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mNoClearingPriceFieldState     == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mNoClearingPriceFieldState     = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mPriceVarIndFieldState         == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mPriceVarIndFieldState         = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mCrossTypeFieldState           == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mCrossTypeFieldState           = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mEventTimeFieldState           == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mEventTimeFieldState           = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mEventSeqNumFieldState         == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mEventSeqNumFieldState         = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mSrcTimeFieldState             == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mSrcTimeFieldState             = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mActTimeFieldState             == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mActTimeFieldState             = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mMsgTypeFieldState             == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mMsgTypeFieldState             = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mIssueSymbolFieldState         == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mIssueSymbolFieldState         = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mPartIdFieldState              == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mPartIdFieldState              = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mSymbolFieldState              == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mSymbolFieldState              = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mSeqNumFieldState              == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mSeqNumFieldState              = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mSecurityStatusOrigFieldState  == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mSecurityStatusOrigFieldState  = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mSecurityStatusTimeFieldState  == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mSecurityStatusTimeFieldState  = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mAuctionTimeFieldState         == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mAuctionTimeFieldState         = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mLineTimeFieldState            == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mLineTimeFieldState            = MamdaFieldState.NOT_MODIFIED;
        if (mOrderImbalanceCache.mSendTimeFieldState            == MamdaFieldState.MODIFIED)
            mOrderImbalanceCache.mSendTimeFieldState            = MamdaFieldState.NOT_MODIFIED;
        }

        private void updateOrderImbalanceFields(
            MamdaSubscription   subscription,
            MamaMsg             msg,
            mamaMsgType         msgType)
        {
            string securityStatus = null;
            lock (this)
            {
                MamaMsgField msgField = null;

                /*The wSecStatusQual will not always be in the message
                so you need to account for this by checking for it.
                */
                try
                {
                    msgField = msg.getField(MamdaOrderImbalanceFields.SECURITY_STATUS_QUAL, null);
                }
                catch (MamdaDataException ex)
                {
                    throw new MamaException(MamaStatus.mamaStatus.MAMA_STATUS_PLATFORM, ex.Message);
                }
                if (msgField == null) //does not exist
                    return;

                securityStatus = msgField.getString();

                if (isImbalanceType(securityStatus))
                {
                    clearCache(mOrderImbalanceCache);
                }
                msg.iterateFields(mFieldIterator, null,null);
            }

            switch (msgType)
            {
                case mamaMsgType.MAMA_MSG_TYPE_INITIAL:
                case mamaMsgType.MAMA_MSG_TYPE_RECAP:
                    handleRecap(subscription, msg);
                    break;
                case mamaMsgType.MAMA_MSG_TYPE_UPDATE:
                {
                    int value = 0;
                    if (securityStatus != null)
                    {
                        value = MamdaOrderImbalanceType.stringToValue(securityStatus);
                        if (MamdaOrderImbalanceType.isMamdaImbalanceOrder(value))
                        {
                            handleOrderImbalance(subscription,msg);
                        }
                        else
                        {
                            handleNoOrderImbalance(subscription, msg);
                        }
                    }
                }
                break;
            default:
                break;
            }

        }

        private static bool isImbalanceType(string securityStatus)
        {
            int value = MamdaOrderImbalanceType.stringToValue(securityStatus);
            return MamdaOrderImbalanceType.isMamdaOrderImbalanceType(value);
        }

        private static ImbalanceOrderUpdate[] createUpdaters()
        {
            mMaxFid = MamdaOrderImbalanceFields.getMaxFid();
            ImbalanceOrderUpdate[] updaters = new ImbalanceOrderUpdate[mMaxFid+1];

            addUpdaterToList(updaters, MamdaOrderImbalanceFields.HIGH_INDICATION_PRICE, new ImbalanceHighIndicationPrice());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.LOW_INDICATION_PRICE, new ImbalanceLowIndicationPrice());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.INDICATION_PRICE, new ImbalanceIndicationPrice());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.BUY_VOLUME, new ImbalanceBuyVolume());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.SELL_VOLUME, new ImbalanceSellVolume());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.MATCH_VOLUME, new ImbalanceMatchVolume());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.SECURITY_STATUS_QUAL, new ImbalanceSecurityStatusQual());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.INSIDE_MATCH_PRICE, new ImbalanceInsideMatchPrice());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.FAR_CLEARING_PRICE, new ImbalanceFarClearingPrice());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.NEAR_CLEARING_PRICE, new ImbalanceNearClearingPrice());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.NO_CLEARING_PRICE, new ImbalanceNoClearingPrice());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.PRICE_VAR_IND, new ImbalancePriceVarInd());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.CROSS_TYPE, new ImbalanceCrossType());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.MSG_TYPE, new ImbalanceMsgType());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.ISSUE_SYMBOL, new ImbalanceIssueSymbol());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.PART_ID, new ImbalancePartId());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.SEQ_NUM, new ImbalanceSeqNum());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.SECURITY_STATUS_ORIG, new ImbalanceSecurityStatusOrig());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.SECURITY_STATUS_TIME, new ImbalanceSecurityStatusTime());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.AUCTION_TIME, new ImbalanceAuctionTime());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.SRC_TIME, new ImbalanceSrcTime());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.ACTIVITY_TIME, new ImbalanceActivityTime());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.LINE_TIME, new ImbalanceLineTime());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.SEND_TIME, new ImbalanceSendTime());
            addUpdaterToList(updaters, MamdaOrderImbalanceFields.SYMBOL, new ImbalanceSymbol());

            return updaters;
        }

        private static void addUpdaterToList(
            ImbalanceOrderUpdate[] updaters,
            MamaFieldDescriptor fieldDesc,
            ImbalanceOrderUpdate updater)
        {
            if (fieldDesc == null) return;
            int fieldId = fieldDesc.getFid();
            if (fieldId <= mMaxFid)
            {
                updaters[fieldId] = updater;
            }
        }

        // Private class used for Field Iteration
        private class FieldIterator : MamaMsgFieldIterator
        {
            public FieldIterator(MamdaOrderImbalanceListener listener)
            {
                mListener = listener;
            }

            public void onField(
                MamaMsg        msg,
                MamaMsgField   field,
                object         closure)
            {
                try
                {
                    int fieldId = field.getFid();
                    if (fieldId <= mMaxFid)
                    {
                        ImbalanceOrderUpdate updater = (ImbalanceOrderUpdate)mUpdaters[fieldId];
                        if (updater != null)
                        {
                            updater.onUpdate(mListener, field);
                        }
                    }
                }
                catch (Exception ex )
                {
                    throw new MamaException(MamaStatus.mamaStatus.MAMA_STATUS_PLATFORM, ex.Message);
                }
            }

            private MamdaOrderImbalanceListener mListener;
        }

        private interface ImbalanceOrderUpdate
        {
            void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field);
        }

        private class ImbalanceHighIndicationPrice : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mHighIndicationPrice.copy(field.getPrice ());
                listener.mOrderImbalanceCache.mHighIndicationPriceFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceLowIndicationPrice : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mLowIndicationPrice.copy(field.getPrice ());
                listener.mOrderImbalanceCache.mLowIndicationPriceFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceIndicationPrice : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mIndicationPrice.copy(field.getPrice ());
                listener.mOrderImbalanceCache.mIndicationPriceFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceBuyVolume : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mBuyVolume = field.getI64 ();
                listener.mOrderImbalanceCache.mBuyVolumeFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceSellVolume : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mSellVolume = field.getI64 ();
                listener.mOrderImbalanceCache.mSellVolumeFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceMatchVolume : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mMatchVolume = field.getI64 ();
                listener.mOrderImbalanceCache.mMatchVolumeFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceSecurityStatusQual : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mSecurityStatusQual = field.getString ();
                listener.mOrderImbalanceCache.mSecurityStatusQualFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceInsideMatchPrice : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mInsideMatchPrice.copy(field.getPrice ());
                listener.mOrderImbalanceCache.mInsideMatchPriceFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceFarClearingPrice : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mFarClearingPrice.copy(field.getPrice ());
                listener.mOrderImbalanceCache.mFarClearingPriceFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceNearClearingPrice : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mNearClearingPrice.copy(field.getPrice ());
                listener.mOrderImbalanceCache.mNearClearingPriceFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceNoClearingPrice : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                switch (field.getType())
                {
                    case mamaFieldType.MAMA_FIELD_TYPE_CHAR :
                        listener.mOrderImbalanceCache.mNoClearingPrice = field.getChar ();
                        listener.mOrderImbalanceCache.mNoClearingPriceFieldState = MamdaFieldState.MODIFIED;
                        break;
                    case mamaFieldType.MAMA_FIELD_TYPE_STRING :
                        if (field.getString() != String.Empty)
                        {
                            listener.mOrderImbalanceCache.mNoClearingPrice = field.getString()[0];
                            listener.mOrderImbalanceCache.mNoClearingPriceFieldState = MamdaFieldState.MODIFIED;
                        }
                        else
                        {
                            listener.mOrderImbalanceCache.mNoClearingPrice = ' ';
                            listener.mOrderImbalanceCache.mNoClearingPriceFieldState = MamdaFieldState.MODIFIED;
                        }
                        break;
                    default : break;
                }
            }
        }

        private class ImbalancePriceVarInd : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                switch (field.getType())
                {
                    case mamaFieldType.MAMA_FIELD_TYPE_CHAR :
                        listener.mOrderImbalanceCache.mPriceVarInd = field.getChar ();
                        listener.mOrderImbalanceCache.mPriceVarIndFieldState = MamdaFieldState.MODIFIED;
                        break;
                    case mamaFieldType.MAMA_FIELD_TYPE_STRING :
                        if (field.getString() != String.Empty)
                        {
                            listener.mOrderImbalanceCache.mPriceVarInd = field.getString ()[0];
                            listener.mOrderImbalanceCache.mPriceVarIndFieldState = MamdaFieldState.MODIFIED;
                        }
                        else
                        {
                            listener.mOrderImbalanceCache.mPriceVarInd = ' ';
                            listener.mOrderImbalanceCache.mPriceVarIndFieldState = MamdaFieldState.MODIFIED;
                        }
                        break;
                    default : break;
                }
            }
        }

        private class ImbalanceCrossType : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                switch (field.getType())
                {
                    case mamaFieldType.MAMA_FIELD_TYPE_CHAR :
                        listener.mOrderImbalanceCache.mCrossType = field.getChar ();
                        listener.mOrderImbalanceCache.mCrossTypeFieldState = MamdaFieldState.MODIFIED;
                        break;
                    case mamaFieldType.MAMA_FIELD_TYPE_STRING :
                        if (field.getString() != String.Empty)
                        {
                            listener.mOrderImbalanceCache.mCrossType = field.getString()[0];
                            listener.mOrderImbalanceCache.mCrossTypeFieldState = MamdaFieldState.MODIFIED;
                        }
                        else
                        {
                            listener.mOrderImbalanceCache.mCrossType = ' ';
                            listener.mOrderImbalanceCache.mCrossTypeFieldState = MamdaFieldState.MODIFIED;
                        }
                        break;
                    default : break;
                }
            }
        }

        private class ImabalanceEventTime : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mEventTime = field.getDateTime ();
                listener.mOrderImbalanceCache.mEventTimeFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceEventSeqNum : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mEventSeqNum = field.getI32 ();
                listener.mOrderImbalanceCache.mEventSeqNumFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceSrcTime : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mSrcTime = field.getDateTime ();
                listener.mOrderImbalanceCache.mSrcTimeFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceActivityTime : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mActTime = field.getDateTime ();
                listener.mOrderImbalanceCache.mActTimeFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceLineTime : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mLineTime = field.getDateTime ();
                listener.mOrderImbalanceCache.mLineTimeFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceSendTime : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mSendTime = field.getDateTime ();
                listener.mOrderImbalanceCache.mSendTimeFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceMsgType : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mMsgType = field.getI32 ();
                listener.mOrderImbalanceCache.mMsgTypeFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceIssueSymbol : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mIssueSymbol = field.getString ();
                listener.mOrderImbalanceCache.mIssueSymbolFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceSymbol : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mSymbol = field.getString ();
                listener.mOrderImbalanceCache.mSymbolFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalancePartId : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mPartId = field.getString ();
                listener.mOrderImbalanceCache.mPartIdFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceSeqNum : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mSeqNum = field.getI32 ();
                listener.mOrderImbalanceCache.mSeqNumFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceSecurityStatusOrig : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mSecurityStatusOrig = field.getString ();
                listener.mOrderImbalanceCache.mSecurityStatusOrigFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceSecurityStatusTime : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mSecurityStatusTime = field.getDateTime ();
                listener.mOrderImbalanceCache.mSecurityStatusTimeFieldState = MamdaFieldState.MODIFIED;
            }
        }

        private class ImbalanceAuctionTime : ImbalanceOrderUpdate
        {
            public void onUpdate(MamdaOrderImbalanceListener listener, MamaMsgField field)
            {
                listener.mOrderImbalanceCache.mAuctionTime = field.getDateTime ();
                listener.mOrderImbalanceCache.mAuctionTimeFieldState = MamdaFieldState.MODIFIED;
            }
        }

        //The following fields are used for caching the offical prices
        //and related fields. These fields can be used by application
        // for reference and will be passed for recaps.
        protected class MamdaOrderImbalanceCache
        {
            public MamaPrice    mHighIndicationPrice = new MamaPrice();
            public MamaPrice    mLowIndicationPrice  = new MamaPrice();
            public MamaPrice    mIndicationPrice     = new MamaPrice();
            public long         mBuyVolume;
            public long         mSellVolume;
            public long         mMatchVolume;
            public String       mSecurityStatusQual;
            public MamaPrice    mInsideMatchPrice    = new MamaPrice();
            public MamaPrice    mFarClearingPrice    = new MamaPrice();
            public MamaPrice    mNearClearingPrice   = new MamaPrice();
            public char         mNoClearingPrice;
            public char         mPriceVarInd;
            public char         mCrossType;
            public DateTime     mEventTime           = DateTime.MinValue;
            public long         mEventSeqNum;
            public DateTime     mSrcTime             = DateTime.MinValue;
            public DateTime     mActTime             = DateTime.MinValue;

            public int          mMsgType;
            public String       mIssueSymbol         = null;
            public String       mPartId              = null;
            public String       mSymbol              = null;
            public int          mSeqNum;
            public String       mSecurityStatusOrig  = null;
            public DateTime     mSecurityStatusTime  = DateTime.MinValue;
            public DateTime     mAuctionTime         = DateTime.MinValue;
            public DateTime     mLineTime            = DateTime.MinValue;
            public DateTime     mSendTime            = DateTime.MinValue;

            //FieldState
            public MamdaFieldState    mHighIndicationPriceFieldState = new MamdaFieldState();
            public MamdaFieldState    mLowIndicationPriceFieldState  = new MamdaFieldState();
            public MamdaFieldState    mIndicationPriceFieldState     = new MamdaFieldState();
            public MamdaFieldState    mBuyVolumeFieldState           = new MamdaFieldState();
            public MamdaFieldState    mSellVolumeFieldState          = new MamdaFieldState();
            public MamdaFieldState    mMatchVolumeFieldState         = new MamdaFieldState();
            public MamdaFieldState    mSecurityStatusQualFieldState  = new MamdaFieldState();
            public MamdaFieldState    mInsideMatchPriceFieldState    = new MamdaFieldState();
            public MamdaFieldState    mFarClearingPriceFieldState    = new MamdaFieldState();
            public MamdaFieldState    mNearClearingPriceFieldState   = new MamdaFieldState();
            public MamdaFieldState    mNoClearingPriceFieldState     = new MamdaFieldState();
            public MamdaFieldState    mPriceVarIndFieldState         = new MamdaFieldState();
            public MamdaFieldState    mCrossTypeFieldState           = new MamdaFieldState();
            public MamdaFieldState    mEventTimeFieldState           = new MamdaFieldState();
            public MamdaFieldState    mEventSeqNumFieldState         = new MamdaFieldState();
            public MamdaFieldState    mSrcTimeFieldState             = new MamdaFieldState();
            public MamdaFieldState    mActTimeFieldState             = new MamdaFieldState();

            public MamdaFieldState    mMsgTypeFieldState             = new MamdaFieldState();
            public MamdaFieldState    mIssueSymbolFieldState         = new MamdaFieldState();
            public MamdaFieldState    mPartIdFieldState              = new MamdaFieldState();
            public MamdaFieldState    mSymbolFieldState              = new MamdaFieldState();
            public MamdaFieldState    mSeqNumFieldState              = new MamdaFieldState();
            public MamdaFieldState    mSecurityStatusOrigFieldState  = new MamdaFieldState();
            public MamdaFieldState    mSecurityStatusTimeFieldState  = new MamdaFieldState();
            public MamdaFieldState    mAuctionTimeFieldState         = new MamdaFieldState();
            public MamdaFieldState    mLineTimeFieldState            = new MamdaFieldState();
            public MamdaFieldState    mSendTimeFieldState            = new MamdaFieldState();
        }

        protected static void clearCache (MamdaOrderImbalanceCache cache)
        {
            cache.mHighIndicationPrice.clear();
            cache.mLowIndicationPrice.clear();
            cache.mIndicationPrice.clear();
            cache.mBuyVolume            = 0;
            cache.mSellVolume           = 0;
            cache.mMatchVolume          = 0;
            cache.mSecurityStatusQual   = null;
            cache.mInsideMatchPrice.clear();
            cache.mFarClearingPrice.clear();
            cache.mNearClearingPrice.clear();
            cache.mNoClearingPrice      = '\0';
            cache.mPriceVarInd          = '\0';
            cache.mCrossType            = '\0';
            cache.mEventTime            = DateTime.MinValue;
            cache.mEventSeqNum          = 0;
            cache.mSrcTime              = DateTime.MinValue;
            cache.mActTime              = DateTime.MinValue;
            cache.mSendTime             = DateTime.MinValue;
            cache.mLineTime             = DateTime.MinValue;

            cache.mMsgType              = 0;
            cache.mIssueSymbol          = null;
            cache.mSymbol               = null;
            cache.mPartId               = null;
            cache.mSeqNum               = 0;
            cache.mSecurityStatusOrig   = null;
            cache.mSecurityStatusTime   = DateTime.MinValue;
            cache.mAuctionTime          = DateTime.MinValue;

            cache.mHighIndicationPriceFieldState    = MamdaFieldState.NOT_INITIALISED;
            cache.mLowIndicationPriceFieldState     = MamdaFieldState.NOT_INITIALISED;
            cache.mIndicationPriceFieldState        = MamdaFieldState.NOT_INITIALISED;
            cache.mBuyVolumeFieldState              = MamdaFieldState.NOT_INITIALISED;
            cache.mSellVolumeFieldState             = MamdaFieldState.NOT_INITIALISED;
            cache.mMatchVolumeFieldState            = MamdaFieldState.NOT_INITIALISED;
            cache.mSecurityStatusQualFieldState     = MamdaFieldState.NOT_INITIALISED;
            cache.mInsideMatchPriceFieldState       = MamdaFieldState.NOT_INITIALISED;
            cache.mFarClearingPriceFieldState       = MamdaFieldState.NOT_INITIALISED;
            cache.mNearClearingPriceFieldState      = MamdaFieldState.NOT_INITIALISED;
            cache.mNoClearingPriceFieldState        = MamdaFieldState.NOT_INITIALISED;
            cache.mPriceVarIndFieldState            = MamdaFieldState.NOT_INITIALISED;
            cache.mCrossTypeFieldState              = MamdaFieldState.NOT_INITIALISED;
            cache.mEventTimeFieldState              = MamdaFieldState.NOT_INITIALISED;
            cache.mEventSeqNumFieldState            = MamdaFieldState.NOT_INITIALISED;
            cache.mSrcTimeFieldState                = MamdaFieldState.NOT_INITIALISED;
            cache.mActTimeFieldState                = MamdaFieldState.NOT_INITIALISED;
            cache.mSendTimeFieldState               = MamdaFieldState.NOT_INITIALISED;
            cache.mLineTimeFieldState               = MamdaFieldState.NOT_INITIALISED;

            cache.mMsgTypeFieldState                = MamdaFieldState.NOT_INITIALISED;
            cache.mIssueSymbolFieldState            = MamdaFieldState.NOT_INITIALISED;
            cache.mSymbolFieldState                 = MamdaFieldState.NOT_INITIALISED;
            cache.mPartIdFieldState                 = MamdaFieldState.NOT_INITIALISED;
            cache.mSeqNumFieldState                 = MamdaFieldState.NOT_INITIALISED;
            cache.mSecurityStatusOrigFieldState     = MamdaFieldState.NOT_INITIALISED;
            cache.mSecurityStatusTimeFieldState     = MamdaFieldState.NOT_INITIALISED;
            cache.mAuctionTimeFieldState            = MamdaFieldState.NOT_INITIALISED;
        }

        #region State

        private ArrayList mHandlers = new ArrayList();
        private MamdaOrderImbalanceSide mSide = MamdaOrderImbalanceSide.ASK_SIDE;

        private static ImbalanceOrderUpdate [] mUpdaters = null;
        private static object mUpdatersGuard = new object();
        private static int mMaxFid = 0;

        protected readonly MamdaOrderImbalanceCache mOrderImbalanceCache =
            new MamdaOrderImbalanceCache ();

        // Used for all field iteration processing
        private FieldIterator mFieldIterator = null;

        #endregion State

        #endregion Implementation details

    }
}

Updated on 2023-03-31 at 15:30:19 +0100