private bool BuildPortfolioRow(List <HugoDataSet.PortfolioRow> subscribeList, List <string> indicesForNetting, HugoDataSet.CurrentPositionsRow positionRow, int updateCounter)
        {
            try
            {
                bool bCheckForNetting;
                bCheckForNetting = false;

                HugoDataSet.PortfolioRow portfolioRow = m_portfolio.Rows.Find(new string[] { positionRow.AcctName, positionRow.Symbol }) as HugoDataSet.PortfolioRow;
                if (portfolioRow == null)
                {
                    bCheckForNetting = true;

                    portfolioRow          = m_portfolio.NewPortfolioRow();
                    portfolioRow.AcctName = positionRow.AcctName;
                    portfolioRow.Symbol   = positionRow.Symbol;

                    if (!positionRow.IsExpirationDateNull())
                    {
                        portfolioRow.ExpirationDate = positionRow.ExpirationDate;
                    }
                    if (!positionRow.IsStrikePriceNull())
                    {
                        portfolioRow.StrikePrice = positionRow.StrikePrice;
                    }
                    if (!positionRow.IsOptionTypeNull())
                    {
                        portfolioRow.OptionType = positionRow.OptionType;
                    }
                    if (!positionRow.IsUnderlyingSymbolNull())
                    {
                        portfolioRow.UnderlyingSymbol = positionRow.UnderlyingSymbol;
                    }

                    // Two multipliers are necessary
                    //  Multiplier is used to determine the deltas on the associated index
                    //  PriceMultiplier is used to determine the market value fo the option itself
                    portfolioRow.Multiplier      = (short)Math.Round(positionRow.Multiplier * positionRow.AssociatedIndexMultiplier, 0);
                    portfolioRow.PriceMultiplier = positionRow.Multiplier;
                    portfolioRow.IsStock         = positionRow.IsStock;
                    portfolioRow.IsOption        = positionRow.IsOption;
                    portfolioRow.IsFuture        = positionRow.IsFuture;
                    m_portfolio.Rows.Add(portfolioRow);
                }
                else
                {
                    // if current position has changed, we must perform netting
                    if (portfolioRow.Current_Position != positionRow.Current_Position)
                    {
                        bCheckForNetting = true;
                    }
                }
                portfolioRow.Current_Position   = positionRow.IsCurrent_PositionNull() ? 0 : positionRow.Current_Position;
                portfolioRow.SOD_Position       = positionRow.IsSOD_PositionNull() ? 0 : positionRow.SOD_Position;
                portfolioRow.SOD_Price          = positionRow.SOD_Price;
                portfolioRow.SOD_Market_Value   = positionRow.SOD_Market_Value;
                portfolioRow.Change_in_Position = positionRow.Change_in_Position;
                portfolioRow.Change_in_Cost     = positionRow.Change_in_Cost;
                portfolioRow.Current_Cost       = positionRow.Current_Cost;
                portfolioRow.UpdateCounter      = updateCounter;

                if (IsSubscribed && (portfolioRow.SubscriptionStatus != SubscriptionStatus.Subscribed.ToString()))
                {
                    // must subscribe to stocks with 0 positions in case we have associated options (so we can calculated dollar deltas)
                    if ((portfolioRow.Current_Position != 0) || (portfolioRow.SOD_Position != 0) || (portfolioRow.IsStock == 1))
                    {
                        portfolioRow.SubscriptionStatus = SubscriptionStatus.Subscribed.ToString();
                        subscribeList.Add(portfolioRow);
                    }
                }

                if (bCheckForNetting)
                {
                    if ((portfolioRow.IsOption == 1) || (portfolioRow.IsFuture == 1))
                    {
                        if (!indicesForNetting.Contains(portfolioRow.UnderlyingSymbol))
                        {
                            indicesForNetting.Add(portfolioRow.UnderlyingSymbol);
                        }
                    }
                }

                return(true);
            }
            catch (Exception ex)
            {
                PositionMonitorUtilities.Error(Name + " unable to build portfolio row", ex);
                return(false);
            }
        }
        private bool PerformNettingForIndex(string index)
        {
            HugoDataSet.PortfolioRow[] allPositionsForIndex = new HugoDataSet.PortfolioRow[0];

            try
            {
                allPositionsForIndex = m_portfolio.Select(String.Format("UnderlyingSymbol = '{0}'", index)) as HugoDataSet.PortfolioRow[];

                // 1.	Set the netted positions in all futures, calls, and puts equal to the actual positions.
                foreach (HugoDataSet.PortfolioRow row in allPositionsForIndex)
                {
                    row.Netting_Adjustment = 0;
                }

                // 2.	Select a future which we have not processed yet.
                var futurePositions = m_portfolio.Select(
                    String.Format("UnderlyingSymbol = '{0}' AND IsFuture=1", index), "ExpirationDate ASC") as HugoDataSet.PortfolioRow[];
                foreach (HugoDataSet.PortfolioRow futurePosition in futurePositions)
                {
                    // 3.	Select the next expiration in which we have both a netted position greater than zero in the selected future and a netted position greater than zero in some put.
                    if ((futurePosition.Current_Position + futurePosition.Netting_Adjustment) > 0)
                    {
                        // 4.	Select the put with the lowest strike price for which we have a netted position greater than zero.
                        HugoDataSet.PortfolioRow[] puts = m_portfolio.Select(String.Format("UnderlyingSymbol = '{0}' AND OptionType='Put' AND ExpirationDate = '{1:d}' AND (([Current Position] + [Netting Adjustment]) > 0)", index, futurePosition.ExpirationDate), "StrikePrice ASC") as HugoDataSet.PortfolioRow[];
                        foreach (HugoDataSet.PortfolioRow put in puts)
                        {
                            // 5.	Calculate the number F as the minimum of
                            // a.	The netted position in the future times the multiplier (usually 50).
                            // b.	The netted position in the selected put times the shares per contract (usually 100).
                            // c.	Minus one times he sum of netted positions of all short calls (i.e., ignoring any calls we are long) times the shares per contract (usually 100)  in strikes equal to or below the strike of the selected put
                            int F = Math.Min((futurePosition.Current_Position + futurePosition.Netting_Adjustment) * futurePosition.Multiplier,
                                             (put.Current_Position + put.Netting_Adjustment) * put.Multiplier);

                            if (F > 0)
                            {
                                HugoDataSet.PortfolioRow[] calls = m_portfolio.Select(String.Format("UnderlyingSymbol = '{0}' AND OptionType='Call' AND ExpirationDate = '{1:d}' AND (([Current Position] + [Netting Adjustment]) < 0) AND StrikePrice <= {2}", index, futurePosition.ExpirationDate, put.StrikePrice), "StrikePrice DESC") as HugoDataSet.PortfolioRow[];
                                int callSum = 0;
                                foreach (HugoDataSet.PortfolioRow call in calls)
                                {
                                    callSum -= (call.Current_Position + call.Netting_Adjustment) * call.Multiplier;
                                }
                                F = Math.Min(F, callSum);

                                //6.	If F is greater than zero, change netted positions as follows, otherwise move on to the next step.
                                if (F > 0)
                                {
                                    // a.	Reduce the netted position of the selected future by F divided by the multiplier.
                                    futurePosition.Netting_Adjustment -= F / futurePosition.Multiplier;

                                    // b.	Reduce the netted position of the selected put by F divided by the shares per contract.
                                    put.Netting_Adjustment -= F / put.Multiplier;

                                    // c.	Select with a call for which we have a negative netted position on a strike equal to or less than the strike
                                    //      of the selected put. Select the call with the highest strike if there is more than one such call.
                                    foreach (HugoDataSet.PortfolioRow call in calls)
                                    {
                                        //d.	Define f as the minimum of F and -1 times the netted position of the selected call times the shares per contract
                                        int f = Math.Min(F, -(call.Current_Position + call.Netting_Adjustment) * call.Multiplier);

                                        // e.	Reduce F by f. Increase the netted position of the selected call by f divided by the shares per contract
                                        F -= f;
                                        call.Netting_Adjustment += f / call.Multiplier;

                                        //f.	If F is still greater than zero, select the next short call position (the next lower strike)
                                        //      and go back to step d. If F is zero or if there is no such call, go on to the next step.
                                        if (F <= 0)
                                        {
                                            break;
                                        }
                                    }
                                }
                            }

                            // 7.	If the netted position in the future is still greater than zero, select the next put (moving to higher strike prices)
                            //      in which we have a netted position greater than zero, and go back to step 5.
                            //      If the netted position in the future is zero or if there is no such put, go back to step 3.
                            if ((futurePosition.Current_Position + futurePosition.Netting_Adjustment) <= 0)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                PositionMonitorUtilities.Error(String.Format("{0} unable to perform netting for {1}", Name, index), ex);

                // undo any calculations
                foreach (HugoDataSet.PortfolioRow row in allPositionsForIndex)
                {
                    row.Netting_Adjustment = 0;
                }
                return(false);
            }
            return(true);
        }