public Form_StockChart(Stock stock)
 {
     InitializeComponent();
     stockLineList = new List<Model_ShockChart>();
     stockLineList.Add(new Model_ShockChart(stock, Color.Blue));
     this.title = "Stock Chart of " + stock.stockCode + ".HK";
 }
Exemple #2
0
        public static void StockToXML(Stock stock, String path)
        {
            string fileName = stock.stockCode + "";
            foreach (SpecialFileName s in Enum.GetValues(typeof(SpecialFileName)))
            {
                if ((int)s == stock.stockCode)
                {
                    stock.stockName = s.ToString();
                    fileName = s.ToString();
                }
            }

            // **********
            // Note: code & example from: http://www.switchonthecode.com/tutorials/csharp-tutorial-xml-serialization
            // **********

            XmlSerializer serializer = new XmlSerializer(typeof(Stock));
            TextWriter textWriter = new StreamWriter(path + "\\" + fileName + ".xml");
            serializer.Serialize(textWriter, stock);
            textWriter.Close();
        }
 public Model_ShockChart(Stock stock, Color color)
 {
     this.stock = stock;
     this.color = color;
     this.color.ToKnownColor();
 }
        static void DownloadStockDate(Stock stock, int d_from, int m_from, int y_from, int d_to, int m_to, int y_to)
        {
            // **********
            // Note: price tick in yahoo finance is in reverse order
            // **********

            String url = String.Format(
                "http://ichart.yahoo.com/table.csv?s={0:0000}.HK&a={1:00}&b={2}&c={3:0000}&d={4:00}&e={5}&f={6:0000}&g=d&ignore=.csv",
                stock.stockCode, m_from - 1, d_from, y_from, m_to - 1, d_to, y_to
                );

            // ^HSI special handling
            if (stock.stockCode == 0)
            {
                url = url.Replace("0000.HK", "^HSI");
            }

            string text = FetchWebsite(url);
            StringReader sr = new StringReader(text);
            string line = sr.ReadLine();
            stock.priceList = new List<Tick>();

            while (true)
            {
                line = sr.ReadLine();

                if (line != null)
                {
                    FakeTick dateTick = new FakeTick();
                    dateTick.Time = new DateTime(
                        int.Parse(line.Substring(0, 4)),
                        int.Parse(line.Substring(5, 2)),
                        int.Parse(line.Substring(8, 2)));

                    stock.priceList.Add(dateTick);
                }
                else
                {
                    break;
                }
            }

            stock.priceList.Reverse();
        }
 static Stock DownloadStock(int stockCode, DateTime dateFrom, DateTime dateTo)
 {
     Stock stock = new Stock();
     stock.stockCode = stockCode;
     DownloadStockDate(stock, dateFrom.Day, dateFrom.Month, dateFrom.Year, dateTo.Day, dateTo.Month, dateTo.Year);
     return stock;
 }
        static void DownloadStockPrice(Stock stock, int d_from, int m_from, int y_from, int d_to, int m_to, int y_to)
        {
            // **********
            // Note: price tick in yahoo finance is in reverse order
            // **********

            String url = String.Format(
                "http://ichart.yahoo.com/table.csv?s={0:0000}.HK&a={1:00}&b={2}&c={3:0000}&d={4:00}&e={5}&f={6:0000}&g=d&ignore=.csv",
                stock.stockCode, m_from - 1, d_from, y_from, m_to - 1, d_to, y_to
                );

            // ^HSI special handling
            if (stock.stockCode == 0)
            {
                url = url.Replace("0000.HK", "^HSI");
            }

            String text = FetchWebsite(url);
            stock.priceList = new List<Tick>();

            // **********
            // Note: csv reader library by Sebastien Lorion: http://www.codeproject.com/KB/database/CsvReader.aspx
            // **********

            NumericTick lastTick = new NumericTick();

            // open the file "data.csv" which is a CSV file with headers
            using (CsvReader csv =
                   new CsvReader(new StringReader(text), true))
            {
                int fieldCount = csv.FieldCount;
                string[] headers = csv.GetFieldHeaders();

                while (csv.ReadNextRecord())
                {
                    // code sample shipped with library
                    // for (int i = 0; i < fieldCount; i++)
                    //    Console.Write(string.Format("{0} = {1};",
                    //                  headers[i], csv[i]));
                    // Console.WriteLine();

                    string tempDate = csv[0];
                    string tempOpen = csv[1];
                    string tempHigh = csv[2];
                    string tempLow = csv[3];
                    string tempClose = csv[4];
                    string volume = csv[5];
                    string adjClose = csv[6];

                    NumericTick newTick = new NumericTick();
                    newTick.Time = new DateTime(
                        int.Parse(tempDate.Substring(0, 4)),
                        int.Parse(tempDate.Substring(5, 2)),
                        int.Parse(tempDate.Substring(8, 2)));

                    newTick.change = 0;
                    newTick.adjustedChange = 0;
                    newTick.high = double.Parse(tempHigh);
                    newTick.low = double.Parse(tempLow);
                    newTick.open = double.Parse(tempOpen);
                    newTick.close = double.Parse(tempClose);
                    newTick.adjustedClose = double.Parse(adjClose);
                    newTick.volume = volume;

                    newTick.id = Identifier.N;

                    if (newTick.close == 0) continue;

                    // add a dummy tick if the price collected is not continuum
                    if (stock.priceList.Count != 0)
                    {
                        for (int i = lastTick.Time.Subtract(newTick.Time).Days; i > 1; i--)
                        {
                            NumericTick dummyTick = new NumericTick();
                            dummyTick.Time = lastTick.Time.AddDays(-1);

                            dummyTick.change = 0;
                            dummyTick.adjustedChange = 0;
                            dummyTick.volume = "0";
                            dummyTick.high = newTick.close;
                            dummyTick.low = newTick.close;
                            dummyTick.open = newTick.close;
                            dummyTick.close = newTick.close;
                            dummyTick.adjustedClose = newTick.adjustedClose;

                            stock.priceList.Add(dummyTick);
                            lastTick = dummyTick;
                        }
                    }

                    stock.priceList.Add(newTick);
                    lastTick = newTick;
                }
            }

            // reverse the tick order to ascending and calculate the change
            stock.priceList.Reverse();
            double lastPrice = 0.0;
            double lastAdjPrice = 0.0;

            foreach (NumericTick eachTick in stock.priceList)
            {
                eachTick.change = ((eachTick.close - lastPrice) * 100);

                if (eachTick.change != 0)
                {
                    eachTick.change /= lastPrice;
                }

                eachTick.adjustedChange = ((eachTick.adjustedClose - lastAdjPrice) * 100);

                if (eachTick.adjustedChange != 0)
                {
                    eachTick.adjustedChange /= lastAdjPrice;
                }

                lastPrice = eachTick.close;
                lastAdjPrice = eachTick.adjustedClose;
            }
        }
        static void DownloadStockCode(List<Stock> list, int mode)
        {
            string url_main = "http://www.hkex.com.hk/eng/market/sec_tradinfo/stockcode/eisdeqty_pf.htm";
            string url_gem = "http://www.hkex.com.hk/eng/market/sec_tradinfo/stockcode/eisdgems_pf.htm";

            // **********
            // Note: regex for stock code & stock name extraction
            // <td.*?>(?<code>[0-9]{5})</td><td.*?><a.*?>(?<name>.*?)</a></td>
            // 
            // Match the characters “<td” literally «<td»
            // Match any single character that is not a line break character «.*?»
            //    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
            // Match the character “>” literally «>»
            // Match the regular expression below and capture its match into backreference with name “code” «(?<code>[0-9]{5})»
            //    Match a single character in the range between “0” and “9” «[0-9]{5}»
            //       Exactly 5 times «{5}»
            // Match the characters “</td><td” literally «</td><td»
            // Match any single character that is not a line break character «.*?»
            //    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
            // Match the characters “><a” literally «><a»
            // Match any single character that is not a line break character «.*?»
            //    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
            // Match the character “>” literally «>»
            // Match the regular expression below and capture its match into backreference with name “name” «(?<name>.*?)»
            //    Match any single character that is not a line break character «.*?»
            //       Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
            // Match the characters “</a></td>” literally «</a></td>»
            // **********

            try
            {
                Regex regexObj = new Regex("<td.*?>(?<code>[0-9]{5})</td><td.*?><a.*?>(?<name>.*?)</a></td>");
                Match matchResult = null;

                if (mode == -1 || mode == -3)
                {
                    // main board
                    matchResult = regexObj.Match(FetchWebsite(url_main));
                    while (matchResult.Success)
                    {
                        Stock newStock = new Stock();
                        newStock.stockCode = int.Parse(matchResult.Groups["code"].Value);
                        newStock.stockName = matchResult.Groups["name"].Value.Trim();
                        list.Add(newStock);
                        matchResult = matchResult.NextMatch();
                    }
                }

                if (mode == -2 || mode == -3)
                {
                    // growth enterprise market
                    matchResult = regexObj.Match(FetchWebsite(url_gem));
                    while (matchResult.Success)
                    {
                        Stock newStock = new Stock();
                        newStock.stockCode = int.Parse(matchResult.Groups["code"].Value);
                        newStock.stockName = matchResult.Groups["name"].Value.Trim();
                        list.Add(newStock);
                        matchResult = matchResult.NextMatch();
                    }
                }
            }
            catch (ArgumentException ex)
            {
                // Syntax error in the regular expression
            }

        }
        static void Main(string[] args)
        {
            int stockCode;
            int d_from;
            int m_from;
            int y_from;
            int d_to;
            int m_to;
            int y_to;
            string filePath;

            Console.WriteLine("########################################");
            Console.WriteLine("# Module:\tFYP_GetStockData");
            Console.WriteLine("# Author:\tThomas Tong");
            Console.WriteLine("# Email:\[email protected]");
            Console.WriteLine("########################################\n");

            if (args.Length != 8 || !int.TryParse(args[0], out stockCode))
            {
                do
                {
                    Console.WriteLine("\nEnter stock code (-1 to get all, 0 to get HSI): ");
                } while (!int.TryParse(Console.ReadLine(), out stockCode));
            }

            if (args.Length != 8 || !int.TryParse(args[1], out y_from))
            {
                do
                {
                    Console.WriteLine("\nEnter starting year (yyyy): ");
                } while (!int.TryParse(Console.ReadLine(), out y_from));
            }

            if (args.Length != 8 || !int.TryParse(args[2], out m_from))
            {
                do
                {
                    Console.WriteLine("\nEnter starting month (mm): ");
                } while (!int.TryParse(Console.ReadLine(), out m_from));
            }

            if (args.Length != 8 || !int.TryParse(args[3], out d_from))
            {
                do
                {
                    Console.WriteLine("\nEnter starting day (dd): ");
                } while (!int.TryParse(Console.ReadLine(), out d_from));
            }

            if (args.Length != 8 || !int.TryParse(args[4], out y_to))
            {
                do
                {
                    Console.WriteLine("\nEnter ending year (yyyy): ");
                } while (!int.TryParse(Console.ReadLine(), out y_to));
            }

            if (args.Length != 8 || !int.TryParse(args[5], out m_to))
            {
                do
                {
                    Console.WriteLine("\nEnter ending month (mm): ");
                } while (!int.TryParse(Console.ReadLine(), out m_to));
            }

            if (args.Length != 8 || !int.TryParse(args[6], out d_to))
            {
                do
                {
                    Console.WriteLine("\nEnter ending day (dd): ");
                } while (!int.TryParse(Console.ReadLine(), out d_to));
            }

            if (args.Length != 8)
            {
                Console.WriteLine("\nEnter store path (e.g. C:\\Temp\\Stock): ");
                filePath = Console.ReadLine();
            }
            else
            {
                filePath = args[7];
            }

            // here we start everything - create directory if not exist
            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }

            if (stockCode >= 0)
            {
                Stock newStock = new Stock();
                newStock.stockCode = stockCode;
                Console.WriteLine("\nDownloading stock price for " + newStock.stockCode + "...");

                try
                {
                    DownloadStockPrice(newStock, d_from, m_from, y_from, d_to, m_to, y_to);
                    ((NumericTick)newStock.priceList.ElementAt(0)).change = 0;
                    ((NumericTick)newStock.priceList.ElementAt(0)).adjustedChange = 0;

                    // health check
                    foreach (NumericTick eachTick in newStock.priceList)
                    {
                        if ((double.IsInfinity(eachTick.change) || double.IsNaN(eachTick.change) ||
                            double.IsInfinity(eachTick.adjustedChange) || double.IsNaN(eachTick.adjustedChange))
                            && !newStock.priceList.ElementAt(0).Equals(eachTick))
                        {
                            Console.WriteLine(newStock.stockCode + " have invalid change % on " + String.Format("{0:yyyyMMdd}", eachTick.Time));

                            // dirty trick
                            eachTick.change = (double.IsInfinity(eachTick.change) || double.IsNaN(eachTick.change)) ? 0 : eachTick.change;
                            eachTick.adjustedChange = (double.IsInfinity(eachTick.adjustedChange) || double.IsNaN(eachTick.adjustedChange)) ? eachTick.change : eachTick.adjustedChange;
                        }
                    }

                    XMLHelper.StockToXML(newStock, @filePath);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            else
            {
                // remove all files in the output folder first - added 8 feb 
                Array.ForEach(Directory.GetFiles(filePath), delegate(string path) { File.Delete(path); });

                List<Stock> stockList = new List<Stock>();
                Console.WriteLine("\nDownloading stock list...");
                DownloadStockCode(stockList, stockCode);
                foreach (Stock eachStock in stockList)
                {
                    Console.WriteLine("\nDownloading stock price for " + eachStock.stockCode + "...");
                    try
                    {
                        DownloadStockPrice(eachStock, d_from, m_from, y_from, d_to, m_to, y_to);
                        ((NumericTick)eachStock.priceList.ElementAt(0)).change = 0;
                        ((NumericTick)eachStock.priceList.ElementAt(0)).adjustedChange = 0;

                        // health check
                        foreach (NumericTick eachTick in eachStock.priceList)
                        {
                            if ((double.IsInfinity(eachTick.change) || double.IsNaN(eachTick.change) ||
                                double.IsInfinity(eachTick.adjustedChange) || double.IsNaN(eachTick.adjustedChange))
                                && !eachStock.priceList.ElementAt(0).Equals(eachTick))
                            {
                                Console.WriteLine(eachStock.stockCode + " have invalid change % on " + String.Format("{0:yyyyMMdd}", eachTick.Time));

                                // dirty trick
                                eachTick.change = (double.IsInfinity(eachTick.change) || double.IsNaN(eachTick.change)) ? 0 : eachTick.change;
                                eachTick.adjustedChange = (double.IsInfinity(eachTick.adjustedChange) || double.IsNaN(eachTick.adjustedChange)) ? eachTick.change : eachTick.adjustedChange;
                            }
                        }

                        Console.WriteLine("Writing stock " + eachStock.stockCode + "...");
                        XMLHelper.StockToXML(eachStock, @filePath);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
            }

            Console.WriteLine("\nProcess exited.");
        }