예제 #1
0
        public static Code toYahooFormat(Code code, Country country)
        {
            if (code == null)
            {
                throw new ArgumentException("Method parameters cannot be null in toYahooFormat");
            }

            Code result = code;

            if (country == Country.Malaysia)
            {
                String _code = code.toString();
                // Index's code start with ^. We will not intrude index's code.
                if (_code.StartsWith("^") == false && _code.EndsWith(".KL") == false)
                {
                    // This is not index's code, and it does not end with .KL.
                    // Let's intrude it!
                    result = Code.newInstance(_code + ".KL");
                }
            }

            return(result);
        }
        public List <Stock> getStocksBySymbols(List <Symbol> symbols)
        {
            List <Stock> stocks = new List <Stock>();

            if (symbols.Count == 0)
            {
                return(stocks);
            }

            int time      = symbols.Count / MAX_STOCK_PER_ITERATION;
            int remainder = symbols.Count % MAX_STOCK_PER_ITERATION;

            for (int i = 0; i < time; i++)
            {
                int start = i * MAX_STOCK_PER_ITERATION;
                int end   = start + MAX_STOCK_PER_ITERATION;

                StringBuilder stringBuilder   = new StringBuilder(getYahooCSVBasedURL());
                StringBuilder symbolBuilder   = new StringBuilder();
                List <Symbol> expectedSymbols = new List <Symbol>();

                int endLoop = end - 1;
                for (int j = start; j < endLoop; j++)
                {
                    String symbolString1 = null;

                    try
                    {
                        //symbolString = java.net.URLEncoder.encode(symbols.get(j).toString(), "UTF-8");
                        symbolString1 = symbols[j].toString();
                    }
                    catch (Exception ex)
                    {
                        throw new StockNotFoundException();
                    }
                    symbolBuilder.Append(symbolString1).Append("+");
                    expectedSymbols.Add(symbols[j]);
                }

                String symbolString = null;

                try
                {
                    //symbolString = java.net.URLEncoder.encode(symbols.get(end - 1).toString(), "UTF-8");
                    symbolString = symbols[end - 1].toString();
                }
                catch (Exception ex)
                {
                    throw new StockNotFoundException();
                }

                symbolBuilder.Append(symbolString);
                expectedSymbols.Add(symbols[end - 1]);

                String _symbol = symbolBuilder.ToString();

                stringBuilder.Append(_symbol).Append(YAHOO_STOCK_FORMAT);

                String location = stringBuilder.ToString();

                bool success = false;

                for (int retry = 0; retry < NUM_OF_RETRY; retry++)
                {
                    String respond = Gui.Utils.getResponseBodyAsStringBasedOnProxyAuthOption(location);

                    if (respond == null)
                    {
                        continue;
                    }

                    List <Stock> tmpStocks = YahooStockFormat.getInstance().parse(respond);
                    if (tmpStocks.Count != MAX_STOCK_PER_ITERATION)
                    {
                        if (retry == (NUM_OF_RETRY - 1))
                        {
                            int currSize     = tmpStocks.Count;
                            int expectedSize = expectedSymbols.Count;

                            if (this.isToleranceAllowed(currSize, expectedSize))
                            {
                                List <Symbol> currSymbols = new List <Symbol>();
                                List <Stock>  emptyStocks = new List <Stock>();

                                foreach (Stock stock in tmpStocks)
                                {
                                    currSymbols.Add(stock.getSymbol());
                                }

                                foreach (Symbol symbol in expectedSymbols)
                                {
                                    if (currSymbols.Contains(symbol) == false)
                                    {
                                        emptyStocks.Add(Gui.Utils.getEmptyStock(Code.newInstance(symbol.toString()), symbol));
                                    }
                                }

                                tmpStocks.AddRange(emptyStocks);
                            }
                            else
                            {
                                throw new StockNotFoundException("Expect " + expectedSize + " stock(s), but only receive " + currSize + " stock(s) from " + location);
                            }
                        } // if (retry == (NUM_OF_RETRY-1))
                        continue;
                    }     // if (tmpStocks.Count != MAX_STOCK_PER_ITERATION)

                    stocks.AddRange(tmpStocks);

                    success = true;
                    break;
                }

                if (success == false)
                {
                    throw new StockNotFoundException("Stock size (" + stocks.Count + ") inconsistent with symbol size (" + symbols.Count + ")");
                }
            }

            int start2 = symbols.Count - remainder;
            int end2   = start2 + remainder;

            StringBuilder stringBuilder2   = new StringBuilder(getYahooCSVBasedURL());
            StringBuilder symbolBuilder2   = new StringBuilder();
            List <Symbol> expectedSymbols2 = new List <Symbol>();

            int endLoop2 = end2 - 1;

            for (int i = start2; i < endLoop2; i++)
            {
                String symbolString = symbols[i].toString();

                symbolBuilder2.Append(symbolString).Append("+");
                expectedSymbols2.Add(symbols[i]);
            }

            String symbolString2 = symbols[end2 - 1].toString();

            symbolBuilder2.Append(symbolString2);
            expectedSymbols2.Add(symbols[end2 - 1]);

            String _symbol2 = symbolBuilder2.ToString();

            stringBuilder2.Append(_symbol2).Append(YAHOO_STOCK_FORMAT);

            String location2 = stringBuilder2.ToString();

            for (int retry = 0; retry < NUM_OF_RETRY; retry++)
            {
                String respond = Gui.Utils.getResponseBodyAsStringBasedOnProxyAuthOption(location2);
                if (respond == null)
                {
                    continue;
                }
                List <Stock> tmpStocks = YahooStockFormat.getInstance().parse(respond);
                if (tmpStocks.Count != remainder)
                {
                    if (retry == (NUM_OF_RETRY - 1))
                    {
                        int currSize     = tmpStocks.Count;
                        int expectedSize = expectedSymbols2.Count;

                        if (this.isToleranceAllowed(currSize, expectedSize))
                        {
                            List <Symbol> currSymbols = new List <Symbol>();
                            List <Stock>  emptyStocks = new List <Stock>();

                            foreach (Stock stock in tmpStocks)
                            {
                                currSymbols.Add(stock.getSymbol());
                            }

                            foreach (Symbol symbol in expectedSymbols2)
                            {
                                if (currSymbols.Contains(symbol) == false)
                                {
                                    emptyStocks.Add(Gui.Utils.getEmptyStock(Code.newInstance(symbol.toString()), symbol));
                                }
                            }

                            tmpStocks.AddRange(emptyStocks);
                        }
                        else
                        {
                            throw new StockNotFoundException("Expect " + expectedSize
                                                             + " stock(s), but only receive " + currSize + " stock(s) from " + location2);
                        }
                    }   // if (retry == (NUM_OF_RETRY-1))

                    continue;
                }   // if (tmpStocks.Count != remainder)

                stocks.AddRange(tmpStocks);

                break;
            }

            if (stocks.Count != symbols.Count)
            {
                throw new StockNotFoundException("Stock size (" + stocks.Count + ") inconsistent with symbol size (" + symbols.Count + ")");
            }

            return(stocks);
        }
예제 #3
0
        private IndexHelper()
        {
            _EnumNames.Add(Index.KLSE, "KLSE");
            _EnumNames.Add(Index.Second, "Second Board");
            _EnumNames.Add(Index.Mesdaq, "Mesdaq");
            _EnumNames.Add(Index.STI, "Straits Times Index");
            _EnumNames.Add(Index.DJI, "Dow Jones Industrial Average");
            _EnumNames.Add(Index.IXIC, "Nasdaq Composite");
            _EnumNames.Add(Index.DAX, "DAX");
            _EnumNames.Add(Index.OMXSPI, "Stockholm General");
            _EnumNames.Add(Index.OMXC20CO, "OMX Copenhagen 20");
            _EnumNames.Add(Index.OSEAX, "OSE All Share");
            _EnumNames.Add(Index.SPMIB, "S&P/MIB");
            _EnumNames.Add(Index.SMSI, "Madrid General");
            _EnumNames.Add(Index.FTSE, "FTSE 100");
            _EnumNames.Add(Index.FCHI, "CAC 40");
            _EnumNames.Add(Index.BSESN, "BSE SENSEX");
            _EnumNames.Add(Index.NSEI, "S&P CNX NIFTY");
            _EnumNames.Add(Index.AORD, "All Ordinaries");
            _EnumNames.Add(Index.ATX, "ATX");
            _EnumNames.Add(Index.BFX, "BEL-20");
            _EnumNames.Add(Index.GSPTSE, "S&P TSX Composite");
            _EnumNames.Add(Index.HSI, "Hang Seng");
            _EnumNames.Add(Index.JKSE, "Jakarta Composite");
            _EnumNames.Add(Index.KS11, "Seoul Composite");
            _EnumNames.Add(Index.AEX, "AEX");
            _EnumNames.Add(Index.PSI20, "PSI 20");
            _EnumNames.Add(Index.TWII, "TSEC weighted index");
            _EnumNames.Add(Index.SSMI, "Swiss Market");
            _EnumNames.Add(Index.BVSP, "Bovespa");
            _EnumNames.Add(Index.SSEC, "China Shanghai Composite");

            _EnumCodes.Add(Index.KLSE, Code.newInstance("^KLSE"));
            _EnumCodes.Add(Index.Second, Code.newInstance("Second"));
            _EnumCodes.Add(Index.Mesdaq, Code.newInstance("Mesdaq"));
            _EnumCodes.Add(Index.STI, Code.newInstance("^STI"));
            _EnumCodes.Add(Index.DJI, Code.newInstance("^DJI"));
            _EnumCodes.Add(Index.IXIC, Code.newInstance("^IXIC"));
            _EnumCodes.Add(Index.DAX, Code.newInstance("^GDAXI"));
            _EnumCodes.Add(Index.OMXSPI, Code.newInstance("^OMXSPI"));
            _EnumCodes.Add(Index.OMXC20CO, Code.newInstance("OMXC20.CO"));
            _EnumCodes.Add(Index.OSEAX, Code.newInstance("^OSEAX"));
            _EnumCodes.Add(Index.SPMIB, Code.newInstance("^SPMIB"));
            _EnumCodes.Add(Index.SMSI, Code.newInstance("^SMSI"));
            _EnumCodes.Add(Index.FTSE, Code.newInstance("^FTSE"));
            _EnumCodes.Add(Index.FCHI, Code.newInstance("^FCHI"));
            _EnumCodes.Add(Index.BSESN, Code.newInstance("^BSESN"));
            _EnumCodes.Add(Index.NSEI, Code.newInstance("^NSEI"));
            _EnumCodes.Add(Index.AORD, Code.newInstance("^AORD"));
            _EnumCodes.Add(Index.ATX, Code.newInstance("^ATX"));
            _EnumCodes.Add(Index.BFX, Code.newInstance("^BFX"));
            _EnumCodes.Add(Index.GSPTSE, Code.newInstance("^GSPTSE"));
            _EnumCodes.Add(Index.HSI, Code.newInstance("^HSI"));
            _EnumCodes.Add(Index.JKSE, Code.newInstance("^JKSE"));
            _EnumCodes.Add(Index.KS11, Code.newInstance("^KS11"));
            _EnumCodes.Add(Index.AEX, Code.newInstance("^AEX"));
            _EnumCodes.Add(Index.PSI20, Code.newInstance("^PSI20"));
            _EnumCodes.Add(Index.TWII, Code.newInstance("^TWII"));
            _EnumCodes.Add(Index.SSMI, Code.newInstance("^SSMI"));
            _EnumCodes.Add(Index.BVSP, Code.newInstance("^BVSP"));
            _EnumCodes.Add(Index.SSEC, Code.newInstance("000001.SS"));
        }
예제 #4
0
        private List <Stock> getStocks(String respond)
        {
            List <Stock> stocks = new List <Stock>();
            // In order to avoid duplicated stock's code.
            HashSet <Code> codes = new HashSet <Code>();

            // A hacking way to prevent
            // <a href="http://uk.finance.yahoo.com/q?s=SCRIA.ST+NCCA.ST+SHBB.ST+ELUXA.ST+LATOA.ST+VOLVA.ST+SCVA.ST+SKFA.ST+SEBC.ST+DV-BTA-1.ST+MTGB.ST+63054.ST+37341.ST+HOLMA.ST+TEL2A.ST+62893.ST+RATOA.ST+585671.ST+">View Quotes for All Above Symbols</a>
            // going into our database. Although we had placed some restriction on the
            // symbol maximum length, it may be some exceptional case sometimes.
            // For example : <a href="http://uk.finance.yahoo.com/q?s=SCRIA.ST+NCCA.ST+">View Quotes for All Above Symbols</a>
            Regex nonSymbolPattern = new Regex("View Quotes for All Above Symbols", RegexOptions.IgnoreCase);

            var matcher = stockAndBoardPattern.Matches(respond);

            for (int i = 1; i <= matcher.Count; i += 3)
            {
                String c = matcher[i].Value;
                if (c == null)
                {
                    continue;
                }

                String s = matcher[i + 1].Value;
                if (s == null)
                {
                    continue;
                }

                String b = matcher[i + 2].Value;
                if (b == null)
                {
                    continue;
                }

                c = c.Trim();
                s = s.Trim();

                // Change Parken Sport &amp; Entertainment A/S to
                // Parken Sport & Entertainment A/S
                s = HttpUtility.HtmlDecode(s);

                if (nonSymbolPattern.IsMatch(s))
                {
                    continue;
                }

                // Enum name is not allowed to have space in between.
                b = b.Trim().Replace("\\s+", "");

                Code        code   = Code.newInstance(c);
                Symbol      symbol = Symbol.newInstance(s);
                Stock.Board board  = Stock.Board.Unknown;

                if (codes.Add(code) == false)
                {
                    // The stock with same code had been added previously. We
                    // do not want any stock with duplicated code.
                    continue;
                }

                // Since '-' character is not allowed in enum, we need some sort
                // of hacking.
                if (b == "Virt-X")
                {
                    b = "Virt_X";
                }

                try
                {
                    board = (Stock.Board)Enum.Parse(typeof(Stock.Board), b);
                }
                catch (ArgumentException exp)
                {
                    log.Error(null, exp);
                    board = Stock.Board.Unknown;
                }

                Stock stock = new Stock(
                    code,
                    symbol,
                    "",
                    board,
                    Stock.Industry.Unknown,
                    0.0,
                    0.0,
                    0.0,
                    0.0,
                    0.0,
                    0,
                    0.0,
                    0.0,
                    0,
                    0.0,
                    0,
                    0.0,
                    0,
                    0.0,
                    0,
                    0.0,
                    0,
                    0.0,
                    0,
                    0.0,
                    0,
                    Calendar.getInstance()
                    );
                stocks.Add(stock);
            }

            return(stocks);
        }
예제 #5
0
        // Update on 19 March 2009 : We cannot assume certain parameters will always
        // be float. They may become integer too. For example, in the case of Korea
        // Stock Market, Previous Close is in integer. We shall apply string quote
        // protection method too on them.
        //
        // Here are the index since 19 March 2009 :
        // (0) Symbol
        // (1) Name
        // (2) Stock Exchange
        // (3) Symbol
        // (4) Previous Close
        // (5) Symbol
        // (6) Open
        // (7) Symbol
        // (8) Last Trade
        // (9) Symbol
        // (10) Day's high
        // (11) Symbol
        // (12) Day's low
        // (13) Symbol
        // (14) Volume
        // (15) Symbol
        // (16) Change
        // (17) Symbol
        // (18) Change Percent
        // (19) Symbol
        // (20) Last Trade Size
        // (21) Symbol
        // (22) Bid
        // (23) Symbol
        // (24) Bid Size
        // (25) Symbol
        // (26) Ask
        // (27) Symbol
        // (28) Ask Size
        // (29) Symbol
        // (30) Last Trade Date
        // (31) Last Trade Time.
        //
        // s = Symbol
        // n = Name
        // x = Stock Exchange
        // o = Open             <-- Although we will keep this value in our stock data structure, we will not show
        //                          it to clients. As some stock servers unable to retrieve open price.
        // p = Previous Close
        // l1 = Last Trade (Price Only)
        // h = Day's high
        // g = Day's low
        // v = Volume           <-- We need to take special care on this, it may give us 1,234. This will
        //                          make us difficult to parse csv file. The only workaround is to make integer
        //                          in between two string literal (which will always Contains "). By using regular
        //                          expression, we will manually remove the comma.
        // c1 = Change
        // p2 = Change Percent
        // k3 = Last Trade Size <-- We need to take special care on this, it may give us 1,234...
        // b = Bid
        // b6 = Bid Size        <-- We need to take special care on this, it may give us 1,234...
        // a = Ask
        // a5 = Ask Size        <-- We need to take special care on this, it may give us 1,234...
        // d1 = Last Trade Date
        // t1 = Last Trade Time
        //
        // c6k2c1p2c -> Change (Real-time), Change Percent (Real-time), Change, Change in Percent, Change & Percent Change
        // "+1400.00","N/A - +4.31%",+1400.00,"+4.31%","+1400.00 - +4.31%"
        //
        // "MAERSKB.CO","AP MOELLER-MAERS-","Copenhagen",32500.00,33700.00,34200.00,33400.00,660,"+1200.00","N/A - +3.69%",33,33500.00,54,33700.00,96,"11/10/2008","10:53am"

        public List <Stock> parse(String source)
        {
            List <Stock> stocks = new List <Stock>();

            if (source == null)
            {
                return(stocks);
            }

            String[] strings = source.Split(new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);

            foreach (String str in strings)
            {
                ///  String tmp = YahooStockFormat.digitPattern.matcher(string).replaceAll("$1");
                var    tmp    = YahooStockFormat.digitPattern.Matches(str);
                string strtmp = YahooStockFormat.digitPattern.Match(str).Value;
                foreach (var item in tmp)
                {
                    // ??
                }

                // Some string contain comma, remove them as well. If not, we face problem during csv parsing.
                String stringDigitWithoutComma = stringCommaPattern.Match(strtmp).Value;

                String[] fields = stringDigitWithoutComma.Split(',');
                int      length = fields.Count();

                Code           code      = null;
                Symbol         symbol    = null;
                String         name      = null;
                Stock.Board    board     = Stock.Board.Unknown;
                Stock.Industry industry  = Stock.Industry.Unknown;
                double         prevPrice = 0.0;
                double         openPrice = 0.0;
                double         lastPrice = 0.0;
                double         highPrice = 0.0;
                double         lowPrice  = 0.0;
                // TODO: CRITICAL LONG BUG REVISED NEEDED.
                long       volume                = 0;
                double     changePrice           = 0.0;
                double     changePricePercentage = 0.0;
                int        lastVolume            = 0;
                double     buyPrice              = 0.0;
                int        buyQuantity           = 0;
                double     sellPrice             = 0.0;
                int        sellQuantity          = 0;
                double     secondBuyPrice        = 0.0;
                int        secondBuyQuantity     = 0;
                double     secondSellPrice       = 0.0;
                int        secondSellQuantity    = 0;
                double     thirdBuyPrice         = 0.0;
                int        thirdBuyQuantity      = 0;
                double     thirdSellPrice        = 0.0;
                int        thirdSellQuantity     = 0;
                SimpleDate calendar              = new SimpleDate();

                do
                {
                    if (length < 1)
                    {
                        break;
                    }
                    code = Code.newInstance(quotePattern.Match(fields[0]).Value.Trim());

                    if (length < 2)
                    {
                        break;
                    }
                    name = quotePattern.Match(fields[1]).Value.Trim();

                    // We use name as symbol, to make it more readable.
                    symbol = Symbol.newInstance(name);

                    if (length < 3)
                    {
                        break;
                    }

                    try
                    {
                        board = (Stock.Board)Enum.Parse(typeof(Stock.Board), quotePattern.Match(fields[2]).Value.Trim());
                    }
                    catch (Exception exp)
                    {
                        board = Stock.Board.Unknown;
                    }

                    industry = Stock.Industry.Unknown;

                    if (length < 5)
                    {
                        break;
                    }
                    try
                    {
                        prevPrice = Double.Parse(fields[4]);
                    }
                    catch (FormatException exp)
                    { }

                    if (length < 7)
                    {
                        break;
                    }
                    try { openPrice = Double.Parse(fields[6]); }
                    catch (FormatException exp) { }

                    if (length < 9)
                    {
                        break;
                    }
                    try { lastPrice = Double.Parse(fields[8]); }
                    catch (FormatException exp) { }

                    if (length < 11)
                    {
                        break;
                    }
                    try { highPrice = Double.Parse(fields[10]); }
                    catch (FormatException exp) { }

                    if (length < 13)
                    {
                        break;
                    }
                    try { lowPrice = Double.Parse(fields[12]); }
                    catch (FormatException exp) { }

                    if (length < 15)
                    {
                        break;
                    }
                    // TODO: CRITICAL LONG BUG REVISED NEEDED.
                    try { volume = long.Parse(fields[14]); }
                    catch (FormatException exp) { }

                    if (length < 17)
                    {
                        break;
                    }
                    try { changePrice = Double.Parse(quotePattern.Match(fields[16]).Value.Trim()); }
                    catch (FormatException exp) { }

                    if (length < 19)
                    {
                        break;
                    }
                    String _changePricePercentage = quotePattern.Match(fields[18]).Value;
                    _changePricePercentage = percentagePattern.Match(_changePricePercentage).Value;
                    try { changePricePercentage = Double.Parse(_changePricePercentage); }
                    catch (FormatException exp) { }

                    if (length < 21)
                    {
                        break;
                    }
                    try { lastVolume = int.Parse(fields[20]); }
                    catch (FormatException exp) { }

                    if (length < 23)
                    {
                        break;
                    }
                    try { buyPrice = Double.Parse(fields[22]); }
                    catch (FormatException exp) { }

                    if (length < 25)
                    {
                        break;
                    }
                    try { buyQuantity = int.Parse(fields[24]); }
                    catch (FormatException exp) { }

                    if (length < 27)
                    {
                        break;
                    }
                    try { sellPrice = Double.Parse(fields[26]); }
                    catch (FormatException exp) { }

                    if (length < 29)
                    {
                        break;
                    }
                    try { sellQuantity = int.Parse(fields[28]); }
                    catch (FormatException exp) { }

                    if (length < 32)
                    {
                        break;
                    }
                    String   data_and_time = quotePattern.Match(fields[28]).Value.Trim() + " " + quotePattern.Match(fields[29]).Value.Trim();
                    DateTime serverDate;
                    try
                    {
                        serverDate = DateTime.ParseExact(data_and_time, "MM/dd/yyyy hh:mmaa", CultureInfo.InvariantCulture);
                        calendar   = new SimpleDate(serverDate);
                    }
                    catch (FormatException exp)
                    {
                        // Most of the time, we just obtain "N/A"
                        // log.error(fields[23] + ", " + fields[24] + ", " + data_and_time, exp);
                    }

                    break;
                } while (true);

                if (code == null || symbol == null || name == null)
                {
                    continue;
                }

                if (calendar == null)
                {
                    calendar = new SimpleDate();
                }

                Stock stock = new Stock(
                    code,
                    symbol,
                    name,
                    board,
                    industry,
                    prevPrice,
                    openPrice,
                    lastPrice,
                    highPrice,
                    lowPrice,
                    volume,
                    changePrice,
                    changePricePercentage,
                    lastVolume,
                    buyPrice,
                    buyQuantity,
                    sellPrice,
                    sellQuantity,
                    secondBuyPrice,
                    secondBuyQuantity,
                    secondSellPrice,
                    secondSellQuantity,
                    thirdBuyPrice,
                    thirdBuyQuantity,
                    thirdSellPrice,
                    thirdSellQuantity,
                    calendar
                    );

                stocks.Add(stock);
            }

            return(stocks);
        }