//
        //
        /// <summary>
        /// This function will setup the instrument matrix.
        /// Also it will find all the trading ratios to generate synthetic fills.
        /// </summary>
        /// <param name="hedgeOptionsCollection"></param>
        /// <returns></returns>
        public bool TrySetupInstrumentMatrix(Dictionary <InstrumentName, HedgeOptions> hedgeOptionsCollection)
        {
            bool isSuccess = false;

            if (m_IsSetup)
            {
                m_Log.NewEntry(LogLevel.Error, "Instrument matrix is already setup, and cannot be setup again.");
                return(isSuccess);
            }
            m_ResultingInstruments = new List <List <ResultingInstrument> >();
            m_TradingRatios        = new List <List <TradingRatio> >();
            for (int x = 0; x < m_InstrumentsList.Count; ++x)
            {
                m_ResultingInstruments.Add(new List <ResultingInstrument>());
                m_TradingRatios.Add(new List <TradingRatio>());
                for (int y = 0; y < m_InstrumentsList.Count; ++y)
                {
                    m_ResultingInstruments[x].Add(new ResultingInstrument());
                    m_TradingRatios[x].Add(new TradingRatio());
                }
            }

            foreach (InstrumentName tradedInstrument in m_InstrumentsList)
            {
                if (hedgeOptionsCollection.ContainsKey(tradedInstrument))
                {
                    HedgeOptions       hedgeOptions    = hedgeOptionsCollection[tradedInstrument];
                    List <HedgeOption> hedgeOptionList = new List <HedgeOption>();
                    if (!hedgeOptions.TryGetHedgeOptions(ref hedgeOptionList))
                    {
                        m_Log.NewEntry(LogLevel.Error, "Failed to get hedge options for quote instrument {0}.", tradedInstrument);
                        return(isSuccess);
                    }
                    foreach (HedgeOption hedgeOption in hedgeOptionList)
                    {
                        InstrumentName hedgeInstrument;
                        int            hedgeRatio;
                        if (TryGetHedgeInstrument(hedgeOption, out hedgeInstrument, out hedgeRatio))
                        {
                            int quoteInstrumentIndex = m_InstrumentsList.IndexOf(tradedInstrument);
                            int hedgeInstrumentIndex = m_InstrumentsList.IndexOf(hedgeInstrument);
                            if (hedgeInstrumentIndex >= 0)
                            {
                                m_ResultingInstruments[quoteInstrumentIndex][hedgeInstrumentIndex] = hedgeOption.ResultingInstrument;
                                TradingRatio tradingRatio = m_TradingRatios[quoteInstrumentIndex][hedgeInstrumentIndex];
                                tradingRatio.QuoteInstrument     = tradedInstrument;
                                tradingRatio.QuoteRatio          = hedgeOption.QuoteWeight;
                                tradingRatio.HedgeInstrument     = hedgeInstrument;
                                tradingRatio.HedgeRatio          = hedgeRatio;
                                tradingRatio.ResultingInstrument = hedgeOption.ResultingInstrument;
                                tradingRatio.ResultingRatio      = hedgeOption.ResultingWeight;
                                if (tradingRatio.QuoteRatio != 0 && tradingRatio.HedgeRatio != 0 && tradingRatio.ResultingRatio != 0)
                                {
                                    m_Log.NewEntry(LogLevel.Minor, "Matrix setup successful at {0}-{1} with instruments {2}-{3}->resulting instrument {4}.",
                                                   quoteInstrumentIndex, hedgeInstrumentIndex, tradedInstrument, hedgeInstrument, hedgeOption.ResultingInstrument);
                                    tradingRatio.IsSet = true;
                                }
                                else
                                {
                                    m_Log.NewEntry(LogLevel.Error,
                                                   "Trading ratio is 0 for quote instrument {0} or hedge instrument {1} or its resulting instrument {2}",
                                                   tradedInstrument, hedgeInstrument, hedgeOption.ResultingInstrument);
                                    //return isSuccess;
                                }
                            }
                            else
                            {
                                m_Log.NewEntry(LogLevel.Error, "Hedge instrument {0} is not a traded instrument for quote instrument {1}.",
                                               hedgeInstrument, tradedInstrument);
                                //return isSuccess;
                            }
                        }
                        else
                        {
                            m_Log.NewEntry(LogLevel.Error, "Failed to get hedge instrument for traded instrument.", tradedInstrument);
                            return(isSuccess);
                        }
                    }
                }
                else
                {
                    m_Log.NewEntry(LogLevel.Error, "The traded instrument {0} does not have hedge options.", tradedInstrument);
                    return(isSuccess);
                }
            }
            m_IsSetup = true;
            isSuccess = true;
            return(isSuccess);
        }
        //
        //
        //
        /// <summary>
        /// This function will find the resulting instrument based on the quote and hedge instruments and their quantities.
        /// The remaining quantities are added because they probably will go to the net open position exposure.
        /// </summary>
        /// <param name="quoteInstrument"></param>
        /// <param name="quoteQty"></param>
        /// <param name="hedgeInstrument"></param>
        /// <param name="hedgeQty"></param>
        /// <param name="resultingInstrument"></param>
        /// <returns></returns>
        public bool TryFindResultingInstrument(InstrumentName quoteInstrument, int quoteQty, InstrumentName hedgeInstrument, int hedgeQty,
                                               out ResultingInstrument resultingInstrument, out int syntheticFillQty, out int quoteRemainingQty, out int hedgeRemainingQty)
        {
            bool isSuccess = false;

            resultingInstrument = null;
            syntheticFillQty    = 0;
            quoteRemainingQty   = 0;
            hedgeRemainingQty   = 0;

            if (Math.Sign(quoteQty * hedgeQty) >= 0)
            {
                m_Log.NewEntry(LogLevel.Error, "Cannot generate synthetic fill as quote instrument {0} with quote qty {1} has same sign as hedge instrument {2} with hedge qty {3}.", quoteInstrument, quoteQty, hedgeInstrument, hedgeQty);
                return(isSuccess);
            }

            // First step: Find the index of the quote instrument and hedge instrument in the list.
            //             They demonstrate the x-y position of these instruments in the matrix.
            //             And then find the corresponding resulting instrument in the matrix.

            int quoteInstrumentIndex = m_InstrumentsList.IndexOf(quoteInstrument);
            int hedgeInstrumentIndex = m_InstrumentsList.IndexOf(hedgeInstrument);

            // If the resulting instrument at a certain position in the matrix is empty, it shows that there are no hedge instruments for these quote instruments found in the database.
            // If the index is wrong, it shows the quote or hedge instrument is not a traded instrument that is input to the matrix at the start of the program.
            if (hedgeInstrumentIndex >= 0)
            {
                if (quoteInstrumentIndex >= 0)
                {
                    if (!m_ResultingInstruments[quoteInstrumentIndex][hedgeInstrumentIndex].IsEmpty)
                    {
                        resultingInstrument = m_ResultingInstruments[quoteInstrumentIndex][hedgeInstrumentIndex];

                        // Second step: Generate synthetic fill for the resulting instrument.
                        //              This will give correct sign for resulting filled quantity.
                        //              Also it will also output the remaining undistributed fills, which may be added to partial repo later.

                        if (quoteInstrumentIndex < m_TradingRatios.Count &&
                            hedgeInstrumentIndex < m_TradingRatios[quoteInstrumentIndex].Count &&
                            m_TradingRatios[quoteInstrumentIndex][hedgeInstrumentIndex] != null &&
                            m_TradingRatios[quoteInstrumentIndex][hedgeInstrumentIndex].IsSet)
                        {
                            TradingRatio tradingRatio   = m_TradingRatios[quoteInstrumentIndex][hedgeInstrumentIndex];
                            int          quoteRatio     = tradingRatio.QuoteRatio;
                            int          hedgeRatio     = tradingRatio.HedgeRatio;
                            int          resultingRatio = tradingRatio.ResultingRatio;

                            // Calculate synthetic fill information
                            int absQuoteFilledQty = Math.Abs(quoteQty);
                            int absHedgeFilledQty = Math.Abs(hedgeQty);
                            int absQuoteRatio     = Math.Abs(quoteRatio);
                            int absHedgeRatio     = Math.Abs(hedgeRatio);
                            int absResultingRatio = Math.Abs(resultingRatio);

                            double floatQuoteFilledQty         = absQuoteFilledQty / absQuoteRatio;
                            double floatHedgeFilledQty         = absHedgeFilledQty / absHedgeRatio;
                            double minFloatQuoteHedgeFilledQty = Math.Min(floatQuoteFilledQty, floatHedgeFilledQty) / absResultingRatio;
                            int    minIntQuoteHedgeFilledQty   = (int)Math.Floor(minFloatQuoteHedgeFilledQty);
                            if (minIntQuoteHedgeFilledQty > 0)
                            {
                                syntheticFillQty = minIntQuoteHedgeFilledQty * Math.Sign(quoteQty * quoteRatio);
                                int quoteQtyChange = minIntQuoteHedgeFilledQty * absResultingRatio * absQuoteRatio * Math.Sign(quoteQty);
                                int hedgeQtyChange = minIntQuoteHedgeFilledQty * absResultingRatio * absHedgeRatio * Math.Sign(hedgeQty);
                                quoteRemainingQty = quoteQty - quoteQtyChange;
                                hedgeRemainingQty = hedgeQty - hedgeQtyChange;
                            }
                            else
                            {
                                // No synthetic fill generated in this case. The quantity is not enough.
                                syntheticFillQty  = 0;
                                quoteRemainingQty = quoteQty;
                                hedgeRemainingQty = hedgeQty;
                                m_StringBuilder.Clear();
                                m_StringBuilder.AppendFormat("No synthetic fill has been generated for quote instrument is {0}, with quote ratio {1} and quote filled qty {2}",
                                                             quoteInstrument, quoteRatio, quoteQty);
                                m_StringBuilder.AppendFormat(" and hedge instrument is {0}, with hedge ratio {1} and hedge filled qty {2}. Resulting instrument weight is {3}.",
                                                             hedgeInstrument, hedgeRatio, hedgeQty, resultingRatio);
                                m_Log.NewEntry(LogLevel.Warning, m_StringBuilder.ToString());
                            }
                            isSuccess = true;
                        }
                        else
                        {
                            m_Log.NewEntry(LogLevel.Error, "Trading ratio is empty/null or not set for quote instrument {0} and hedge instrument {1}.",
                                           quoteInstrument, hedgeInstrument);
                            return(isSuccess);
                        }
                    }
                    else
                    {
                        m_Log.NewEntry(LogLevel.Error, "Resulting instrument is empty for quote instrument {0} and hedge instrument {1}.",
                                       quoteInstrument, hedgeInstrument);
                        return(isSuccess);
                    }
                }
                else
                {
                    m_Log.NewEntry(LogLevel.Error, "Quote instrument {0} is not a traded instrument.", quoteInstrument);
                    return(isSuccess);
                }
            }
            else
            {
                m_Log.NewEntry(LogLevel.Error, "Hedge instrument {0} is not a traded instrument.", hedgeInstrument);
                return(isSuccess);
            }
            return(isSuccess);
        }