Exemple #1
0
        private StockItem ParseStockLine(string stockText, SectorItem sector)
        {
            StockItem stock = new StockItem(_pseDocument, sector);

            string[] stockInfo = stockText.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            if (stockInfo.Length < 10)
            {
                //throw new Exception(string.Format("Invalid stock line: {0}", stockText));
                _errorLine = stockText.Trim();
                return(null);
            }

            // easier to work from end of the array first
            stockInfo = stockInfo.Reverse <string>().ToArray <string>();

            double?doubleValue = stockInfo[0].ParseDouble();

            stock.NetForeignBuy = doubleValue.HasValue ? (double)doubleValue : 0;

            doubleValue = stockInfo[1].ParseDouble();
            stock.Value = doubleValue.HasValue ? (double)doubleValue : 0;

            ulong?uLongValue = stockInfo[2].ParseUlong();

            stock.Volume = uLongValue.HasValue ? (ulong)uLongValue : 0;

            doubleValue = stockInfo[3].ParseDouble();
            stock.Close = doubleValue.HasValue ? (double)doubleValue : 0;

            doubleValue = stockInfo[4].ParseDouble();
            stock.Low   = doubleValue.HasValue ? (double)doubleValue : 0;

            doubleValue = stockInfo[5].ParseDouble();
            stock.High  = doubleValue.HasValue ? (double)doubleValue : 0;

            doubleValue = stockInfo[6].ParseDouble();
            stock.Open  = doubleValue.HasValue ? (double)doubleValue : 0;

            doubleValue = stockInfo[7].ParseDouble();
            stock.Ask   = doubleValue.HasValue ? (double)doubleValue : 0;

            doubleValue = stockInfo[8].ParseDouble();
            stock.Bid   = doubleValue.HasValue ? (double)doubleValue : 0;

            stock.Symbol = stockInfo[9];

            // build the stock description
            int index            = 9;
            var stockDescription = string.Empty;

            for (int i = stockInfo.Length - 1; i > index; i--)
            {
                stockDescription = stockDescription + stockInfo[i] + " ";
            }

            stock.Description = stockDescription.Trim();

            return(stock);
        }
Exemple #2
0
        public SectorDef(LocationDef location, SectorItem sectorItem)
        {
            string sectorSetupError = (new StarTrekKGSettings()).GetText("SectorDefSetupError");

            if (location.Sector.X < Constants.SECTOR_MIN)
            {
                throw new GameConfigException(sectorSetupError + " Sector x < " + Constants.SECTOR_MIN);
            }

            if (location.Sector.X > Constants.SECTOR_MAX)
            {
                throw new GameConfigException(sectorSetupError + " Sector x > " + Constants.SECTOR_MAX);
            }

            if (location.Sector.Y < Constants.SECTOR_MIN)
            {
                throw new GameConfigException(sectorSetupError + "Sector y < " + Constants.SECTOR_MIN);
            }

            if (location.Sector.Y > Constants.SECTOR_MAX)
            {
                throw new GameConfigException(sectorSetupError + "Sector y > " + Constants.SECTOR_MAX);
            }

            this.Sector    = new Sector(new LocationDef(location.Region, new Coordinate(location.Sector.X, location.Sector.Y)));
            this.Item      = sectorItem;
            this.RegionDef = location.Region;
        }
Exemple #3
0
        public SectorDef(SectorItem sectorItem)
        {
            this.Sector = new Sector(new LocationDef(Coordinate.GetRandom(), Coordinate.GetRandom()));

            //todo: if this Region already has a starbase, then don't assign.
            //check this.RegionDef.  If starbase exists, and sectorItem is a starbase, then assign empty instead.
            this.Item = sectorItem;
        }
Exemple #4
0
        private void ParseSectorSummary()
        {
            var pattern = @"\b(Financials|Industrials|Holding Firms|Property|Services|Mining & Oil|SME|ETF|PSEi|All Shares|GRAND TOTAL)\s\b([0-9,\.\s\(\)\-]+)";

            MatchCollection matches = Regex.Matches(_reportString, pattern);

            for (var sectorIndex = 0; sectorIndex < matches.Count; sectorIndex++)
            {
                GroupCollection matchCol = matches[sectorIndex].Groups;

                // index match
                var      indexName = matchCol[1].Value;
                string[] row       = matchCol[2].Value.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Reverse <string>().ToArray <string>();

                if (indexName == "PSEi" || indexName == "All Shares")
                {
                    SectorItem sectorItem = _pseDocument.Sectors[sectorIndex];
                    sectorItem.PointChange   = double.Parse(row[0], NumberStyles.Any);
                    sectorItem.PercentChange = double.Parse(row[1], NumberStyles.Any);
                    sectorItem.Close         = double.Parse(row[2], NumberStyles.Any);
                    sectorItem.Low           = double.Parse(row[3], NumberStyles.Any);
                    sectorItem.High          = double.Parse(row[4], NumberStyles.Any);
                    sectorItem.Open          = double.Parse(row[5], NumberStyles.Any);
                }
                else if (indexName == "GRAND TOTAL")
                {
                    SectorItem sectorItem = _pseDocument.GetSector(PSEDocument.PSEI);
                    sectorItem.Value  = double.Parse(row[0], NumberStyles.Any);
                    sectorItem.Volume = ulong.Parse(row[1], NumberStyles.Any);
                }
                else
                {
                    SectorItem sectorItem = _pseDocument.Sectors[sectorIndex];
                    if (sectorItem != null)
                    {
                        sectorItem.Value  = double.Parse(row[0], NumberStyles.Any);
                        sectorItem.Volume = ulong.Parse(row[1], NumberStyles.Any);

                        // SME and ETF contains only two elements: Volume and Value
                        if (sectorItem.Symbol == PSEDocument.SME || sectorItem.Symbol == PSEDocument.ETF)
                        {
                            continue;
                        }

                        sectorItem.Open          = double.Parse(row[7], NumberStyles.Any);
                        sectorItem.High          = double.Parse(row[6], NumberStyles.Any);
                        sectorItem.Low           = double.Parse(row[5], NumberStyles.Any);
                        sectorItem.Close         = double.Parse(row[4], NumberStyles.Any);
                        sectorItem.PercentChange = double.Parse(row[3], NumberStyles.Any);
                        sectorItem.PointChange   = double.Parse(row[2], NumberStyles.Any);
                    }
                }
            }
        }
Exemple #5
0
 /// <summary>
 /// goes through each sector in this Region and clears item requested
 /// </summary>
 /// <returns></returns>
 public void ClearSectorsWithItem(SectorItem item)
 {
     if (this.Sectors != null)
     {
         var sectorsWithItem = this.Sectors.Where(sector => sector.Item == item);
         foreach (var sector in sectorsWithItem)
         {
             sector.Item   = SectorItem.Empty;
             sector.Object = null;
         }
     }
     else
     {
         throw new GameException(this.Map.Config.GetSetting <string>("DebugNoSetUpSectorsInRegion") + this.Name +
                                 ".");
     }
 }
        private void ParseForeignTransaction()
        {
            // foreign buy/sell
            var               pattern = @"(FOREIGN\s+)(BUYING|SELLING):\s+Php\s([0-9\.\s,\(\)\-]+)";
            MatchCollection   matches = Regex.Matches(_reportString, pattern);
            Nullable <double> nfb     = null;
            Nullable <double> nfs     = null;

            nfb = matches[0].Groups[3].Value.ParseDouble();
            nfs = matches[1].Groups[3].Value.ParseDouble();
            SectorItem psei = _pseDocument.GetSector(PSEDocument.PSEI);

            psei.NetForeignBuy = Math.Round((double)nfb - (double)nfs, 2);

            _pseDocument.TotalForeignBuying  = (double)nfb;
            _pseDocument.TotalForeignSelling = (double)nfs;
        }
Exemple #7
0
        public void AddSector(Region Region, int x, int y, SectorItem itemToPopulate, Stack <string> stockBaddieNames,
                              FactionName stockBaddieFaction)
        {
            var newlyCreatedSector = Sector.CreateEmpty(Region, new Coordinate(x, y));

            this.Map.Write.DebugLine("Added new Empty Sector to Region: " + Region.Name + " Coordinate: " +
                                     newlyCreatedSector);

            if (itemToPopulate == SectorItem.HostileShip)
            {
                //if a baddie name is passed, then use it.  otherwise
                var newShip = this.CreateHostileShip(newlyCreatedSector, stockBaddieNames, stockBaddieFaction, this.Game);
                Region.AddShip(newShip, newlyCreatedSector);
            }
            else
            {
                newlyCreatedSector.Item = itemToPopulate;
            }

            Region.Sectors.Add(newlyCreatedSector);
        }
Exemple #8
0
        private void IdentifyObstacle(ICoordinate sector, ISectorObject currentObject, SectorItem currentItem)
        {
            switch (currentItem)
            {
            case SectorItem.Star:
                var star = currentObject;
                this.Game.Write.Line("Stellar body " + star.Name.ToUpper() + " encountered while navigating at sector: [" + sector.X + "," +
                                     sector.Y + "]");
                break;

            case SectorItem.HostileShip:
                var hostile = currentObject;
                this.Game.Write.Line("Ship " + hostile.Name + " encountered while navigating at sector: [" + sector.X + "," +
                                     sector.Y + "]");
                break;


            case SectorItem.Starbase:
                this.Game.Write.Line("Starbase encountered while navigating at sector: [" + sector.X + "," + sector.Y + "]");
                break;

            default:
                this.Game.Write.Line("Detected an unidentified obstacle while navigating at sector: [" + sector.X + "," + sector.Y + "]");
                break;
            }
        }
        public void TestReader_SectorSummary()
        {
            var stripper = new PDFTextStripper();
            var reader   = new PSEReportReader(stripper.getText(doc).TrimEnd());

            var pd = new PSEDocument();

            reader.Fill(pd);

            // psei
            SectorItem psei = pd.GetSector(PSEDocument.PSEI);

            ulong expected = 7786326861;
            ulong actual   = psei.Volume;

            Assert.AreEqual(expected, actual, "PSEi volume not equal");

            double expected_value = 12960265679.1516;
            double actual_value   = pd.GetSector(PSEDocument.PSEI).Value;

            Assert.AreEqual(expected_value, actual_value, "PSEi value not equal");

            expected_value = 3979.97;
            actual_value   = psei.Open;
            Assert.AreEqual(expected_value, actual_value, "PSEi open not equal");

            expected_value = 4053.32;
            actual_value   = psei.High;
            Assert.AreEqual(expected_value, actual_value, "PSEi high not equal");

            expected_value = 3979.97;
            actual_value   = psei.Low;
            Assert.AreEqual(expected_value, actual_value, "PSEi low not equal");

            expected_value = 4053.32;
            actual_value   = psei.Close;
            Assert.AreEqual(expected_value, actual_value, "PSEi close not equal");


            // financial
            SectorItem financial = pd.GetSector(PSEDocument.FINANCIAL);

            expected = 24780801;
            actual   = financial.Volume;

            Assert.AreEqual(expected, actual, "Financial volume not equal");

            expected_value = 882690827.9;
            actual_value   = financial.Value;

            Assert.AreEqual(expected, actual, "Financial value not equal");

            //913.01 935.52 909.34 935.52 2.47 22.51 24,780,801 882,690,827.9
            expected_value = 913.01;
            actual_value   = financial.Open;

            Assert.AreEqual(expected_value, actual_value, "Financial open not equal");

            expected_value = 935.52;
            actual_value   = financial.High;

            Assert.AreEqual(expected_value, actual_value, "Financial high not equal");

            expected_value = 909.34;
            actual_value   = financial.Low;

            Assert.AreEqual(expected_value, actual_value, "Financial low not equal");

            expected_value = 935.52;
            actual_value   = financial.Close;

            Assert.AreEqual(expected_value, actual_value);


            // mining
            SectorItem mining = pd.GetSector(PSEDocument.MINING_OIL);

            expected = 3832444034;
            actual   = mining.Volume;

            Assert.AreEqual(expected, actual, "Mining volume not equal");

            expected_value = 977394265.25;
            actual_value   = mining.Value;

            Assert.AreEqual(expected, actual, "Mining value not equal");

            //11,644.77 12,468.64 11,644.77 12,387.7 7.97 914.68 3,832,444,034 977,394,265.25

            expected_value = 11644.77;
            actual_value   = mining.Open;

            Assert.AreEqual(expected_value, actual_value);

            expected_value = 12468.64;
            actual_value   = mining.High;

            Assert.AreEqual(expected_value, actual_value);

            expected_value = 11644.77;
            actual_value   = mining.Low;

            Assert.AreEqual(expected_value, actual_value);

            expected_value = 12387.7;
            actual_value   = mining.Close;

            Assert.AreEqual(expected_value, actual_value);

            SectorItem pse = pd.GetSector(PSEDocument.PSEI);

            expected_value = 1938423893.11;
            actual_value   = pse.NetForeignBuy;

            Assert.AreEqual(expected_value, actual_value);
        }
Exemple #10
0
        public void TestReader_SectorSummary()
        {
            //PDFTextStripper stripper = new PDFTextStripper();
            IPdfService pdfService = new PdfTextSharpService();
            var         reader     = new PSEReportReader2();

            var pd = new PSEDocument();

            reader.Fill(pd, pdfService.ExtractTextFromPdf(pdfDocPath));

            // psei
            SectorItem psei = pd.GetSector(PSEDocument.PSEI);

            ulong expected = 3150242905;
            ulong actual   = psei.Volume;

            Assert.AreEqual(expected, actual, "PSEi volume not equal");

            double expected_value = 5634576802.26;
            double actual_value   = pd.GetSector(PSEDocument.PSEI).Value;

            Assert.AreEqual(expected_value, actual_value, "PSEi value not equal");

            expected_value = 7007.63;
            actual_value   = psei.Open;
            Assert.AreEqual(expected_value, actual_value, "PSEi open not equal");

            expected_value = 7011.28;
            actual_value   = psei.High;
            Assert.AreEqual(expected_value, actual_value, "PSEi high not equal");

            expected_value = 6986.86;
            actual_value   = psei.Low;
            Assert.AreEqual(expected_value, actual_value, "PSEi low not equal");

            expected_value = 6999.75;
            actual_value   = psei.Close;
            Assert.AreEqual(expected_value, actual_value, "PSEi close not equal");


            // financial
            SectorItem financial = pd.GetSector(PSEDocument.FINANCIAL);

            expected = 8105540;
            actual   = financial.Volume;

            Assert.AreEqual(expected, actual, "Financial volume not equal");

            expected_value = 755542372.19;
            actual_value   = financial.Value;

            Assert.AreEqual(expected, actual, "Financial value not equal");

            //913.01 935.52 909.34 935.52 2.47 22.51 24,780,801 882,690,827.9
            expected_value = 1585.35;
            actual_value   = financial.Open;

            Assert.AreEqual(expected_value, actual_value, "Financial open not equal");

            expected_value = 1585.39;
            actual_value   = financial.High;

            Assert.AreEqual(expected_value, actual_value, "Financial high not equal");

            expected_value = 1577.85;
            actual_value   = financial.Low;

            Assert.AreEqual(expected_value, actual_value, "Financial low not equal");

            expected_value = 1583.44;
            actual_value   = financial.Close;

            Assert.AreEqual(expected_value, actual_value);


            // mining
            SectorItem mining = pd.GetSector(PSEDocument.MINING_OIL);

            expected = 2528326978;
            actual   = mining.Volume;

            Assert.AreEqual(expected, actual, "Mining volume not equal");

            expected_value = 143087427.64;
            actual_value   = mining.Value;

            Assert.AreEqual(expected, actual, "Mining value not equal");

            //11,644.77 12,468.64 11,644.77 12,387.7 7.97 914.68 3,832,444,034 977,394,265.25

            expected_value = 10885.19;
            actual_value   = mining.Open;

            Assert.AreEqual(expected_value, actual_value);

            expected_value = 10886.63;
            actual_value   = mining.High;

            Assert.AreEqual(expected_value, actual_value);

            expected_value = 10700.58;
            actual_value   = mining.Low;

            Assert.AreEqual(expected_value, actual_value);

            expected_value = 10740.09;
            actual_value   = mining.Close;

            Assert.AreEqual(expected_value, actual_value);

            SectorItem pse = pd.GetSector(PSEDocument.PSEI);

            expected_value = -616052104.21;
            actual_value   = pse.NetForeignBuy;

            Assert.AreEqual(expected_value, actual_value);
        }
        //When implemented:
        //INitialize
        //AddHostile - get rid of sector.addhostile
        //CreateHostileX
        //Populate
        //AddEmptySector
        //GetItem
        //OutOfBounds

        public void SetUpNewRegionWith(SectorItem item)
        {
            //throws in a random number of SectorItem
        }
Exemple #12
0
        /// <summary>
        /// Parse stock information into pseDocument object
        /// </summary>
        /// <param name="pseDocument"></param>
        private void ParseReportBody(PSEDocument pseDocument)
        {
            SectorItem        sector      = null;
            Nullable <ulong>  uLongValue  = null;
            Nullable <double> doubleValue = null;

            foreach (string s in this.reportBody)
            {
                //retrieve the sector object then move on to the next line
                if (sectorNameMap.ContainsValue(s))
                {
                    sector = pseDocument.GetSector(sectorNameMap.GetKey(s));
                    bool parseCondition = (s == sectorNameMap[PSEDocument.PREFERRED]) ||
                                          (s == sectorNameMap[PSEDocument.SME]) ||
                                          (s == sectorNameMap[PSEDocument.WARRANT]);

                    if (DateTime.Compare(_tradeDate, _reportChangeDate1) >= 0)
                    {
                        parseCondition = parseCondition || s == sectorNameMap[PSEDocument.DEPOSITORY_RECEIPTS];
                    }

                    if (DateTime.Compare(_tradeDate, _reportChangeDate2) >= 0)
                    {
                        parseCondition = parseCondition || s == sectorNameMap[PSEDocument.ETF];
                    }

                    if (DateTime.Compare(_tradeDate, _reportChangeDate3) >= 0)
                    {
                        parseCondition = parseCondition || s == sectorNameMap[PSEDocument.DOLLAR_DONOMINATED_SECURITIES];
                    }

                    if (parseCondition)
                    {
                        var subSector = new SubSectorItem();
                        subSector.Name = s;
                        sector.SubSectors.Add(subSector);
                    }

                    continue;
                }

                string[] row = s.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                if (row[0] == "****")
                {
                    // retrieve the subsector then create the subsector object
                    // continue to the next line after
                    var subSector = new SubSectorItem();

                    string subSectorName = s.Replace("****", null);
                    subSector.Name = subSectorName.Trim();
                    sector.SubSectors.Add(subSector);
                    continue;
                }

                // skip volume summary
                if (s.Contains("TOTAL VOLUME"))
                {
                    continue;
                }
                if (sector.SubSectors.Count == 0)
                {
                    sector.SubSectors.Add(new SubSectorItem()
                    {
                        Name = "UNKNOWN"
                    });
                }
                // now load stock information into the subsector object

                row = row.Reverse <string>().ToArray <string>();


                SubSectorItem currentSubSector = sector.SubSectors[sector.SubSectors.Count - 1]; // always points to the last added subsector

                //Name Symbol Bid Ask Open High Low Close Volume Value NB/S
                //in reverse order

                StockItem stock = new StockItem(pseDocument, sector);

                doubleValue         = row[0].ParseDouble();
                stock.NetForeignBuy = doubleValue.HasValue ? (double)doubleValue : 0;

                doubleValue = row[1].ParseDouble();
                stock.Value = doubleValue.HasValue ? (double)doubleValue : 0;

                uLongValue   = row[2].ParseUlong();
                stock.Volume = uLongValue.HasValue ? (ulong)uLongValue : 0;

                doubleValue = row[3].ParseDouble();
                stock.Close = doubleValue.HasValue ? (double)doubleValue : 0;

                doubleValue = row[4].ParseDouble();
                stock.Low   = doubleValue.HasValue ? (double)doubleValue : 0;

                doubleValue = row[5].ParseDouble();
                stock.High  = doubleValue.HasValue ? (double)doubleValue : 0;

                doubleValue = row[6].ParseDouble();
                stock.Open  = doubleValue.HasValue ? (double)doubleValue : 0;

                doubleValue = row[7].ParseDouble();
                stock.Ask   = doubleValue.HasValue ? (double)doubleValue : 0;

                doubleValue = row[8].ParseDouble();
                stock.Bid   = doubleValue.HasValue ? (double)doubleValue : 0;

                stock.Symbol = row[9];


                int           index = 9;
                StringBuilder sb    = new StringBuilder();
                for (int i = row.Length - 1; i > index; i--)
                {
                    sb.Append(row[i] + " ");
                }

                stock.Description = sb.ToString().TrimEnd();

                currentSubSector.Stocks.Add(stock);
            }
        }
Exemple #13
0
        private void ParseSectorSummary(PSEDocument pseDocument)
        {
            string[]          row;
            int               i   = 0;
            Nullable <double> nfb = null;
            Nullable <double> nfs = null;

            foreach (string s in this.sectorSummary)
            {
                row = s.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Reverse <string>().ToArray <string>();

                //OPEN HIGH LOW CLOSE %CHANGE PT.CHANGE VOLUME VALUE

                SectorItem sectorItem = pseDocument.Sectors[i];

                if (s.Contains("PSEi") || s.Contains("All Shares"))
                {
                    sectorItem.PointChange   = double.Parse(row[0], NumberStyles.Any);
                    sectorItem.PercentChange = double.Parse(row[1], NumberStyles.Any);
                    sectorItem.Close         = double.Parse(row[2], NumberStyles.Any);
                    sectorItem.Low           = double.Parse(row[3], NumberStyles.Any);
                    sectorItem.High          = double.Parse(row[4], NumberStyles.Any);
                    sectorItem.Open          = double.Parse(row[5], NumberStyles.Any);
                }
                else if (s.Contains("GRAND TOTAL"))
                {
                    sectorItem       = pseDocument.GetSector(PSEDocument.PSEI);
                    sectorItem.Value = double.Parse(row[0], NumberStyles.Any);
                    if (DateTime.Compare(_tradeDate, _reportChangeDate1) >= 0)
                    {
                        sectorItem.Volume = ulong.Parse(row[1], NumberStyles.Any);
                    }
                    else
                    {
                        sectorItem.Volume = ulong.Parse(row[2], NumberStyles.Any);
                    }
                }
                else if (s.Contains("SME") || s.Contains("ETF"))
                {
                    continue;
                }
                else if (s.Contains("FOREIGN"))
                {
                    if (s.Contains("FOREIGN BUYING"))
                    {
                        nfb = row[0].ParseDouble();
                        if (!nfb.HasValue)
                        {
                            nfb = 0;
                        }
                    }
                    if (s.Contains("FOREIGN SELLING"))
                    {
                        nfs = row[0].ParseDouble();
                        if (!nfs.HasValue)
                        {
                            nfs = 0;
                        }
                        // nothing more to parse after foreign selling
                        break;
                    }
                }
                else if (s.Contains("and Block Sale transactions.") ||
                         s.Contains("NET FOREIGN") ||
                         s.Contains("TOTAL FOREIGN"))
                {
                    continue;
                }
                else
                {
                    sectorItem.Open          = double.Parse(row[7], NumberStyles.Any);
                    sectorItem.High          = double.Parse(row[6], NumberStyles.Any);
                    sectorItem.Low           = double.Parse(row[5], NumberStyles.Any);
                    sectorItem.Close         = double.Parse(row[4], NumberStyles.Any);
                    sectorItem.PercentChange = double.Parse(row[3], NumberStyles.Any);
                    sectorItem.PointChange   = double.Parse(row[2], NumberStyles.Any);
                    sectorItem.Volume        = ulong.Parse(row[1], NumberStyles.Any);
                    sectorItem.Value         = double.Parse(row[0], NumberStyles.Any);
                }
                i++;
            }

            SectorItem psei = pseDocument.GetSector(PSEDocument.PSEI);

            psei.NetForeignBuy = Math.Round((double)nfb - (double)nfs, 2);

            //calculate sector netforeign buying/selling
            foreach (SectorItem sectorItem in pseDocument.Sectors)
            {
                if (sectorItem.Symbol == "^PSEi")
                {
                    continue;
                }
                sectorItem.NetForeignBuy = 0;
                foreach (SubSectorItem subSectorItem in sectorItem.SubSectors)
                {
                    foreach (StockItem stockItem in subSectorItem.Stocks)
                    {
                        sectorItem.NetForeignBuy += stockItem.NetForeignBuy;
                    }
                }
            }
        }
Exemple #14
0
 public StockItem(PSEDocument ownerDocument, SectorItem ownerSector)
     : base(ownerDocument)
 {
     OwnerSector = ownerSector;
 }
        private void ParseReportBody()
        {
            string[]      lines     = _reportString.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
            SectorItem    sector    = null;
            SubSectorItem subSector = null;

            foreach (var line in lines)
            {
                // end of the line
                var pattern = @"(TOTAL MAIN BOARD.+\s+)(.+)";
                if (Regex.Match(line, pattern).Success)
                {
                    break;
                }

                // create the sector object
                pattern = @"\b([A-Z&\.,]\s+)+([A-Z])\b";
                Match sectorTextMatch = Regex.Match(line, pattern);
                if (sectorTextMatch.Success)
                {
                    var sectorKey = sectorNameMap.GetKey(sectorTextMatch.Value);
                    Debug.Assert(sectorKey != null, "Unable to locate sector key" + sectorTextMatch.Value);
                    sector = _pseDocument.GetSector(sectorKey);

                    // not all sectors have sub-sectors.
                    // we have to null this to make sure stocks don't get mixed up in other sectors
                    subSector = null;
                    continue;
                }

                // sub sector
                // proceed to next line if matched
                pattern = @"(\*+\s+)(.+\s)(.\*+)";
                Match match = Regex.Match(line, pattern);
                if (match.Success)
                {
                    Debug.Assert(sector != null, "Unable to initialize the sector object.");
                    subSector      = new SubSectorItem();
                    subSector.Name = match.Groups[2].Value.Trim();
                    sector.SubSectors.Add(subSector);
                    continue;
                }

                // will only match stocks that has trading activity
                pattern = @"\b([\w]+\s)+\b([0-9\.\s,\(\)\-]+)";

                // malformed report line looks like this
                // 506,200 8,042,620 4,009,350
                // LT GROUP LTG 15.9 15.98 15.78 15.98 15.78 15.9
                var stockLine = line;
                if (_errorLine != string.Empty)
                {
                    // fix the malformed line
                    stockLine  = line + " " + _errorLine;
                    _errorLine = string.Empty; // reset
                }

                if (Regex.Match(stockLine, pattern).Success)
                {
                    // found the stock line
                    Debug.Assert(sector != null, "Unable to initialize the sector object.");

                    if (subSector == null)
                    {
                        // not all sectors have sub-sectors so we create a default
                        subSector      = new SubSectorItem();
                        subSector.Name = "DEFAULT";
                        sector.SubSectors.Add(subSector);
                    }

                    StockItem stock = ParseStockLine(stockLine, sector);
                    if (stock != null)
                    {
                        subSector.Stocks.Add(stock);
                    }
                }
            }

            //calculate sector netforeign buying/selling
            foreach (SectorItem sectorItem in _pseDocument.Sectors)
            {
                if (sectorItem.Symbol == "^PSEi")
                {
                    continue;
                }
                sectorItem.NetForeignBuy = 0;
                foreach (SubSectorItem subSectorItem in sectorItem.SubSectors)
                {
                    foreach (StockItem stockItem in subSectorItem.Stocks)
                    {
                        sectorItem.NetForeignBuy += stockItem.NetForeignBuy;
                    }
                }
            }
        }