internal FrmStockEdit(Stock stockF, bool actionIsAdd)
        {
            NewAddedStock = null;

            InitializeComponent();
            ActionIsAdd = actionIsAdd;
            EditingStock = stockF;
            NumHoldCount.Value = EditingStock.HoldCount;
            NumHoldPrice.Value = (decimal)EditingStock.HoldPrice;
            LabelCodeVal.Text = EditingStock.Code;
            LabelNameVal.Text = EditingStock.Name;
            ComboNum1.SelectedIndex = 0;
            ComboOperator.SelectedIndex = 0;

            CheckShowInTitleBar.Checked = EditingStock.ShowInTitleBar;
            CheckAlarm.Checked = EditingStock.ShowWarning;
            CheckAlarm_CheckdChanged(null, null);

            if (EditingStock.WarningConditions != null)
                foreach (string s in EditingStock.WarningConditions)
                    ListConditions.Items.Add(s);
            RadioAnd.Checked = !
                (RadioOr.Checked = EditingStock.IsOrWarnCondi ? true : false);

            Program.ConfigChanged += Program_ConfigChanged;
            Program_ConfigChanged(null, null);
        }
示例#2
0
 internal Stock[] ToStockArray()
 {
     Stock[] rtn = new Stock[Stocks.Count];
     int i = 0;
     foreach (DictionaryEntry de in Stocks)
     {
         rtn[i++] = Stocks[de.Key] as Stock;
     }
     return rtn;
 }
示例#3
0
 internal FrmKLine(Stock stock)
 {
     InitializeComponent();
     FlashMain.BGColor = Program.Config.KLineStyle == "黑色" ? "000000" : "FFFFFF";
     LabelLoading.BackColor = Program.Config.KLineStyle == "黑色" ? Color.Black : Color.White;
     Text = string.Format("{0}({1})", stock.Name, stock.Code);
     Program.ConfigChanged += Program_ConfigChanged;
     Program_ConfigChanged(null, null);
     FlashMain.Movie = string.Format("http://flashhq.gw.com.cn/tab.swf?font=0&flashdzh_theme={2}&stk_list=分时线,{0},{1},1,2; 日线,{0},{1},2,0;周线,{0},{1},2,1;月线,{0},{1},2,2;1分钟,{0},{1},2,3;5分钟,{0},{1},2,4;15分钟,{0},{1},2,5;30分钟,{0},{1},2,6;60分钟,{0},{1},2,7", stock.Area == "sh" ? "1" : "2", stock.Code, Program.Config.KLineStyle == "黑色" ? "Black" : "White");
     FlashMain.Play();
 }
        private bool UpdateGvMain(Stock stock)
        {
            decimal holdTotal;
            decimal total;
            decimal pl;
            decimal plPer;
            CalcStock(stock, out holdTotal, out total, out pl, out plPer);

            bool isUpdate = false;
            foreach (DataGridViewRow row in GvMain.Rows)
            {
                if (row.Tag as string != stock.Area + stock.Code) continue;
                if (row.Cells["GvmColArrow"].Visible)
                    row.Cells["GvmColArrow"].Value = stock.UpDown > 0 ? Properties.Resources.arrow_up_16x16
                        : stock.UpDown < 0 ? Properties.Resources.arrow_down_16x16 : Properties.Resources.square_16x16;
                if (row.Cells["GvmColBell"].Visible)
                {
                    row.Cells["GvmColBell"].Value = stock.ShowWarning ? Properties.Resources.bell_on_16x16 : Properties.Resources.null_16x16;
                    row.Cells["GvmColBell"].ToolTipText = stock.ShowWarning ? "点击关闭股票预警" : "点击开启股票预警";
                }

                if (row.Cells["GvmColShowInTitle"].Visible)
                    row.Cells["GvmColShowInTitle"].Value = stock.ShowInTitleBar ? Properties.Resources.showintitle_on_16x16 : Properties.Resources.null_16x16;

                if (row.Cells["GvmColShowInTitle"].Visible)
                    row.Cells["GvmColShowInTitle"].ToolTipText = stock.ShowInTitleBar ? "点击关闭标题栏行情" : "点击开启标题栏行情";

                if (row.Cells["GvmColMyStock"].Visible)
                {
                    row.Cells["GvmColMyStock"].Value = stock.HoldCount > 0 ? Properties.Resources.gold_16x16 : Properties.Resources.null_16x16;
                    row.Cells["GvmColMyStock"].ToolTipText = stock.HoldCount > 0 ? string.Format("当前持有{0}股", stock.HoldCount.ToString("n0")) : "当前未持有此股票";
                }

                if (row.Cells["GvmColChart"].Visible && stock.ChartIcon != null)
                    row.Cells["GvmColChart"].Value = stock.ChartIcon;

                if (row.Cells["GvmColCode"].Visible)
                    row.Cells["GvmColCode"].Value = stock.Code;
                if (row.Cells["GvmColPinyin"].Visible)
                    row.Cells["GvmColPinyin"].Value = stock.Pinyin;
                if (row.Cells["GvmColName"].Visible)
                    row.Cells["GvmColName"].Value = stock.Name;
                if (row.Cells["GvmColRateForDay"].Visible)
                {
                    row.Cells["GvmColRateForDay"].Value = stock.RateForDay.RateString;
                    row.Cells["GvmColRateForDay"].ToolTipText = string.IsNullOrEmpty(stock.RateForDay.RateString) ? "暂无日评信息" : stock.RateForDay.RateDate.ToString("日评时间: yyyy-MM-dd");
                }
                if (row.Cells["GvmColMarket"].Visible)
                    row.Cells["GvmColMarket"].Value = stock.AreaChinese;
                if (row.Cells["GvmColPriceClose"].Visible)
                    row.Cells["GvmColPriceClose"].Value = stock.PriceClose;
                if (row.Cells["GvmColPriceOpen"].Visible)
                    row.Cells["GvmColPriceOpen"].Value = stock.PriceOpen;

                if (row.Cells["GvmColPriceCurrent"].Visible)
                {
                    if (row.Cells["GvmColPriceCurrent"].Value != null)
                    {
                        decimal priceCurrentOld = decimal.Parse(row.Cells["GvmColPriceCurrent"].Value.ToString().Replace(" +", "").Replace(" -", "").Replace(" =", ""));
                        row.Cells["GvmColPriceCurrent"].Value = stock.PriceCurrent > priceCurrentOld ? (stock.PriceCurrent.ToString() + " +") :
                            stock.PriceCurrent < priceCurrentOld ? (stock.PriceCurrent + " -") : (stock.PriceCurrent + " =");
                    }
                    else row.Cells["GvmColPriceCurrent"].Value = stock.PriceCurrent + " =";
                }
                if (row.Cells["GvmColUpDown"].Visible)
                    row.Cells["GvmColUpDown"].Value = stock.UpDown;
                if (row.Cells["GvmColUpDownPer"].Visible)
                    row.Cells["GvmColUpDownPer"].Value = stock.UpDownPer;
                if (row.Cells["GvmColHoldCount"].Visible)
                    row.Cells["GvmColHoldCount"].Value = stock.HoldCount;
                if (row.Cells["GvmColHoldPrice"].Visible)
                    row.Cells["GvmColHoldPrice"].Value = stock.HoldPrice;
                if (row.Cells["GvmColTotal"].Visible)
                    row.Cells["GvmColTotal"].Value = total;
                if (row.Cells["GvmColProfit"].Visible)
                    row.Cells["GvmColProfit"].Value = pl;
                if (row.Cells["GvmColProfitPer"].Visible)
                    row.Cells["GvmColProfitPer"].Value = plPer;
                if (row.Cells["GvmColMaxPrice"].Visible)
                    row.Cells["GvmColMaxPrice"].Value = stock.PriceMax;
                if (row.Cells["GvmColMinPrice"].Visible)
                    row.Cells["GvmColMinPrice"].Value = stock.PriceMin;
                if (row.Cells["GvmColBusinessAmount"].Visible)
                    row.Cells["GvmColBusinessAmount"].Value = stock.BusinessAmount;
                if (row.Cells["GvmColBusinessVolume"].Visible)
                    row.Cells["GvmColBusinessVolume"].Value = stock.BusinessQty;
                if (row.Cells["GvmColBuy1"].Visible)
                    row.Cells["GvmColBuy1"].Value = stock.QtyBuy1.ToString("n0") + "/" + stock.PriceBuy1;
                if (row.Cells["GvmColBuy2"].Visible)
                    row.Cells["GvmColBuy2"].Value = stock.QtyBuy2.ToString("n0") + "/" + stock.PriceBuy2;
                if (row.Cells["GvmColBuy3"].Visible)
                    row.Cells["GvmColBuy3"].Value = stock.QtyBuy3.ToString("n0") + "/" + stock.PriceBuy3;
                if (row.Cells["GvmColBuy4"].Visible)
                    row.Cells["GvmColBuy4"].Value = stock.QtyBuy4.ToString("n0") + "/" + stock.PriceBuy4;
                if (row.Cells["GvmColBuy5"].Visible)
                    row.Cells["GvmColBuy5"].Value = stock.QtyBuy5.ToString("n0") + "/" + stock.PriceBuy5;
                if (row.Cells["GvmColSell1"].Visible)
                    row.Cells["GvmColSell1"].Value = stock.QtySell1.ToString("n0") + "/" + stock.PriceSell1;
                if (row.Cells["GvmColSell2"].Visible)
                    row.Cells["GvmColSell2"].Value = stock.QtySell2.ToString("n0") + "/" + stock.PriceSell2;
                if (row.Cells["GvmColSell3"].Visible)
                    row.Cells["GvmColSell3"].Value = stock.QtySell3.ToString("n0") + "/" + stock.PriceSell3;
                if (row.Cells["GvmColSell4"].Visible)
                    row.Cells["GvmColSell4"].Value = stock.QtySell4.ToString("n0") + "/" + stock.PriceSell4;
                if (row.Cells["GvmColSell5"].Visible)
                    row.Cells["GvmColSell5"].Value = stock.QtySell5.ToString("n0") + "/" + stock.PriceSell5;
                if (row.Cells["GvmColDate"].Visible)
                    row.Cells["GvmColDate"].Value = stock.UpdateTime.ToString("yyyy-MM-dd");
                if (row.Cells["GvmColTime"].Visible)
                    row.Cells["GvmColTime"].Value = stock.UpdateTime.ToString("HH:mm:ss");
                if (row.Cells["GvmColSwing"].Visible)
                    row.Cells["GvmColSwing"].Value = stock.Swing;
                if (row.Cells["GvmColRate"].Visible)
                    row.Cells["GvmColRate"].Value = stock.TurnoverRate;
                if (row.Cells["GvmColHoldTotal"].Visible)
                    row.Cells["GvmColHoldTotal"].Value = holdTotal;
                if (row.Cells["GvmColOuter"].Visible)
                    row.Cells["GvmColOuter"].Value = stock.OuterVolume;
                if (row.Cells["GvmColInner"].Visible)
                    row.Cells["GvmColInner"].Value = stock.InnerVolume;
                if (row.Cells["GvmColHighLimit"].Visible)
                    row.Cells["GvmColHighLimit"].Value = stock.HighLimit;
                if (row.Cells["GvmColLowLimit"].Visible)
                    row.Cells["GvmColLowLimit"].Value = stock.LowLimit;
                if (row.Cells["GvmColPe"].Visible)
                    row.Cells["GvmColPe"].Value = stock.PriceEarning;

                foreach (DataGridViewCell cell in row.Cells)
                {
                    if (cell.Style.Tag as string == "UserFormated") continue;

                    cell.Style.ForeColor = stock.UpDown > 0 ? Program.Config.GvMainForeColorUp
                        : stock.UpDown < 0 ? Program.Config.GvMainForeColorDown : Program.Config.GvMainForeColorStill;
                }
                isUpdate = true;
                break;
            }

            int upCount = 0;
            int downCount = 0;
            decimal totalAmount = 0;
            decimal totalHold = 0;
            decimal totalPl = 0;

            foreach (DictionaryEntry de in Program.UserData.Stocks)
            {
                decimal total1;
                decimal holdTotal1;
                decimal pl1;
                decimal plPer1;

                Stock sTemp = de.Value as Stock;
                CalcStock(sTemp, out holdTotal1, out total1, out pl1, out plPer1);

                if (sTemp.UpDown > 0)
                    upCount++;
                else if (sTemp.UpDown < 0)
                    downCount++;
                totalAmount += total1;
                totalPl += pl1;
                totalHold += holdTotal1;
            }

            LabelStat.Text = string.Format("股票: {0}    涨/跌: {1}/{2}    成本合计: {3}    累计现值: {4}    累计收益: {5}/{6}%", GvMain.Rows.Count, upCount, downCount, totalHold.ToString("c", CultureInfo.GetCultureInfo(0x0804)), totalAmount.ToString("c", CultureInfo.GetCultureInfo(0x0804)), totalPl.ToString("c", CultureInfo.GetCultureInfo(0x0804)), totalHold > 0 ? Math.Round(totalPl / totalHold * 100, 2).ToString("n2") : "0.00");
            if (LabelStat.Image != Properties.Resources.stat_16x16)
                LabelStat.Image = Properties.Resources.stat_16x16;

            return isUpdate;
        }
        private void ShowWarning(Stock stock)
        {
            if (!stock.ShowWarning)
                return;

            decimal holdTotal;
            decimal total;
            decimal pl;
            decimal plPer;
            CalcStock(stock, out holdTotal, out total, out pl, out plPer);

            //判断是否满足预警条件
            bool isContented = false;
            foreach (string s in stock.WarningConditions)
            {
                string[] s1 = s.Split(' ');
                decimal num1 = 0;
                decimal num2 = decimal.Parse(s1[2]);
                switch (s1[0])
                {
                    case "股票价格":
                        num1 = stock.PriceCurrent;
                        break;
                    case "涨跌额":
                        num1 = stock.UpDown;
                        break;
                    case "涨跌幅":
                        num1 = stock.UpDownPer;
                        break;
                    case "振幅":
                        num1 = stock.Swing;
                        break;
                    case "换手率":
                        num1 = stock.TurnoverRate ?? 0;
                        break;
                    case "总现值":
                        num1 = total;
                        break;
                    case "收益":
                        num1 = pl;
                        break;
                    case "收益率":
                        num1 = plPer;
                        break;
                    case "最高价":
                        num1 = stock.PriceMax;
                        break;
                    case "最低价":
                        num1 = stock.PriceMin;
                        break;
                    case "成交量":
                        num1 = stock.BusinessQty;
                        break;
                    case "成交额":
                        num1 = stock.BusinessAmount;
                        break;
                    case "外盘":
                        num1 = stock.OuterVolume;
                        break;
                    case "内盘":
                        num1 = stock.InnerVolume;
                        break;
                }

                //比较
                switch (s1[1])
                {
                    case "大于":
                        isContented = num1 > num2;
                        break;
                    case "小于":
                        isContented = num1 < num2;
                        break;
                    case "等于":
                        isContented = num1 == num2;
                        break;

                }

                if (stock.IsOrWarnCondi && isContented)
                    break;
            }

            //通过, 窗口提示
            if (!isContented) return;

            StringBuilder text = new StringBuilder();
            foreach (string item in stock.WarningConditions)
            {
                text.AppendFormat("{0}{1}{2} ", item, Environment.NewLine, stock.IsOrWarnCondi ? "或者" : "并且");
            }

            if (text.Length > 3)
                text = text.Remove(text.Length - 3, 3);

            FrmAlarm frmAlarm = new FrmAlarm();
            frmAlarm.Tag = stock.Area + stock.Code;
            if (frmAlarm.ShowAlarm(this, string.Format("{0}({1})已满足预警条件, 请注意!", stock.Name, stock.Code), text.ToString()) == DialogResult.OK)
            {
                if (!Visible)
                    MiShowHide_Click(null, null);
                GvMainSelectRow(stock.Area + stock.Code);
                UpdateGvMain(stock);
            }
        }
        private void ShowStocks(Stock[] stocks)
        {
            foreach (Stock stock in stocks)
            {
                //GvMain中还没有该股票, 添加.
                if (!UpdateGvMain(stock))
                {
                    DataGridViewRow row = new DataGridViewRow();
                    row.Tag = stock.Area + stock.Code;
                    GvMain.Rows.Add(row);
                    GvMain.ClearSelection();
                    if (GvMain.Rows[GvMain.Rows.Count - 1] != null && GvMain.CurrentCell != null)
                    {
                        GvMain.Rows[GvMain.Rows.Count - 1].Selected = true;
                        GvMain.CurrentCell = GvMain.Rows[GvMain.Rows.Count - 1].Cells[GvMain.CurrentCell.ColumnIndex];
                    }

                    //再次调用UpdateLvWish
                    UpdateGvMain(stock);
                }

                //预警显示
                ShowWarning(stock);
            }

            if (!IsFirstShowStocks) return;
            //排序列
            GvMain.Sort(GvMain.Columns[Program.Config.SortColumn.ColumnName], Program.Config.SortColumn.Order);
            IsFirstShowStocks = false;
        }
 private void ShowChartPreview(Stock stock)
 {
     FrmChart.ChartUrl = string.Format(
            "http://bdchart.hexun.com/stock/chart/bf/{0}/{1}.png?{2}", stock.Area == "sh" ? "0" : "1", stock.Code, new Random().NextDouble());
     FrmChart.MutexObject.Set();
     if (FrmChart.Visible) return;
     FrmChart.Show(this);
     GvMain.Focus();
 }
 // Private Methods (17)
 private void CalcStock(Stock stock, out decimal holdTotal, out decimal total, out decimal pl, out decimal plPer)
 {
     holdTotal = stock.HoldPrice * stock.HoldCount;
     total = stock.PriceCurrent * stock.HoldCount;
     pl = total - holdTotal;
     plPer = holdTotal > 0 ? Math.Round(pl / holdTotal * 100, 2) : 0;
 }
示例#9
0
        public static bool[] UpdateStockData(Stock[] stockList)
        {
            if (stockList.Length == 0) return new bool[] { false };

            bool[] ret = new bool[stockList.Length];
            WebClient wc = new WebClient();

            //构造查询URL
            StringBuilder reqUrl = new StringBuilder(string.Format(StockDataUrl, new Random().NextDouble()));
            for (int i = 0; i < stockList.Length; i++)
                reqUrl.Append(stockList[i].Area + stockList[i].Code + ",");
            reqUrl = reqUrl.Remove(reqUrl.Length - 1, 1);

            //查询数据
            wc.Encoding = Encoding.GetEncoding(936);
            string dataStr = wc.DownloadString(reqUrl.ToString());
            string[] dataStrLines = dataStr.Split(new char[] { ';', '\n' }, StringSplitOptions.RemoveEmptyEntries);

            //更新数据
            for (int i = 0; i < stockList.Length; i++) {
                Regex regex = new Regex(string.Format("v_{0}=\"(.*?)\"", stockList[i].Area + stockList[i].Code));
                Match m = regex.Match(dataStrLines[i]);
                string[] dataSplit;
                if (!m.Success || (dataSplit = m.Groups[1].Value.Split('~')).Length < 51) {
                    ret[i] = false;
                    continue;
                }
                stockList[i].PriceCurrent = Convert.ToDecimal(dataSplit[3]);
                stockList[i].PriceClose = Convert.ToDecimal(dataSplit[4]);
                stockList[i].PriceOpen = Convert.ToDecimal(dataSplit[5]);
                stockList[i].OuterVolume = Convert.ToInt32(dataSplit[7]);
                stockList[i].InnerVolume = Convert.ToInt32(dataSplit[8]);
                stockList[i].PriceBuy1 = Convert.ToDecimal(dataSplit[9]);
                stockList[i].QtyBuy1 = Convert.ToInt32(dataSplit[10]);
                stockList[i].PriceBuy2 = Convert.ToDecimal(dataSplit[11]);
                stockList[i].QtyBuy2 = Convert.ToInt32(dataSplit[12]);
                stockList[i].PriceBuy3 = Convert.ToDecimal(dataSplit[13]);
                stockList[i].QtyBuy3 = Convert.ToInt32(dataSplit[14]);
                stockList[i].PriceBuy4 = Convert.ToDecimal(dataSplit[15]);
                stockList[i].QtyBuy4 = Convert.ToInt32(dataSplit[16]);
                stockList[i].PriceBuy5 = Convert.ToDecimal(dataSplit[17]);
                stockList[i].QtyBuy5 = Convert.ToInt32(dataSplit[18]);
                stockList[i].PriceSell1 = Convert.ToDecimal(dataSplit[19]);
                stockList[i].QtySell1 = Convert.ToInt32(dataSplit[20]);
                stockList[i].PriceSell2 = Convert.ToDecimal(dataSplit[21]);
                stockList[i].QtySell2 = Convert.ToInt32(dataSplit[22]);
                stockList[i].PriceSell3 = Convert.ToDecimal(dataSplit[23]);
                stockList[i].QtySell3 = Convert.ToInt32(dataSplit[24]);
                stockList[i].PriceSell4 = Convert.ToDecimal(dataSplit[25]);
                stockList[i].QtySell4 = Convert.ToInt32(dataSplit[26]);
                stockList[i].PriceSell5 = Convert.ToDecimal(dataSplit[27]);
                stockList[i].QtySell5 = Convert.ToInt32(dataSplit[28]);

                //逐笔
                string[] runnings = dataSplit[29].Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                stockList[i].RunningList = new RunningStruct[runnings.Length];
                for (int j = 0; j < runnings.Length; j++) {
                    string[] runnings2 = runnings[j].Split(new char[] { '/' });
                    stockList[i].RunningList[j].Time = Convert.ToDateTime(runnings2[0]);
                    stockList[i].RunningList[j].Price = Convert.ToDecimal(runnings2[1]);
                    stockList[i].RunningList[j].Volume = Convert.ToInt32(runnings2[2]);
                    stockList[i].RunningList[j].IsBuy = runnings2[3] == "B" ? true : false;
                }

                DateTime updateTime = DateTime.ParseExact(dataSplit[30], "yyyyMMddHHmmss", CultureInfo.InvariantCulture);
                stockList[i].UpdateTime = updateTime;

                stockList[i].UpDown = Convert.ToDecimal(dataSplit[31]);
                stockList[i].UpDownPer = Convert.ToDecimal(dataSplit[32]);

                stockList[i].PriceMax = Convert.ToDecimal(dataSplit[33]);
                stockList[i].PriceMin = Convert.ToDecimal(dataSplit[34]);
                stockList[i].BusinessQty = Convert.ToInt64(dataSplit[36]);
                stockList[i].BusinessAmount = Convert.ToDecimal(dataSplit[37]);

                decimal turnoverRate;
                stockList[i].TurnoverRate = decimal.TryParse(dataSplit[38], out turnoverRate) ? turnoverRate as decimal? : null;

                decimal priceEarning;
                stockList[i].PriceEarning = decimal.TryParse(dataSplit[39], out priceEarning) ? priceEarning as decimal? : null;

                stockList[i].Swing = Convert.ToDecimal(dataSplit[43]);
                stockList[i].HighLimit = Convert.ToDecimal(dataSplit[47]);
                stockList[i].LowLimit = Convert.ToDecimal(dataSplit[48]);

                //更新GoogleCompanyId;
                if (stockList[i].GoogleCompanyId == null)
                    stockList[i].GoogleCompanyId = stockList[i].GetGoogleCompanyId();

                //更新RateForDay
                if (stockList[i].RateForDay.RequestTime < DateTime.Now.Date)
                    stockList[i].RateForDay = stockList[i].GetRateForDay();
                ret[i] = true;
            }
            return ret;
        }
示例#10
0
        public static void UpdateStockChartIcon(Stock[] stockList)
        {
            WebClient wc = new WebClient();

            //构造查询URL
            StringBuilder reqUrl = new StringBuilder(ChartIconUrl);
            foreach (Stock s in stockList)
                if (s.GoogleCompanyId != null)
                    reqUrl.Append(s.GoogleCompanyId + ",");

            //获取Chart图片
            byte[] chartBytes = wc.DownloadData(reqUrl.ToString());
            using (MemoryStream ms = new MemoryStream(chartBytes)) {
                using (Image img = Bitmap.FromStream(ms)) {
                    for (int i = 0, j = 0; i < stockList.Length; i++) {
                        if (stockList[i].GoogleCompanyId != null) {
                            Bitmap bmp = new Bitmap(50, 15, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

                            //裁剪Chart图片
                            using (Graphics g = Graphics.FromImage(bmp)) {
                                g.DrawImage(img, 0, 0, new Rectangle(0, j, 50, 15), GraphicsUnit.Pixel);
                                j += 15;
                            }
                            stockList[i]._ChartIcon = bmp;

                        } else
                            stockList[i]._ChartIcon = Properties.Resources.nomini;
                    }
                }
            }
        }
示例#11
0
        public static List<Stock> LoadStockSource(string lstFile)
        {
            List<Stock> stocks = new List<Stock>();
            using (StreamReader reader = new StreamReader(File.Open(lstFile, FileMode.Open, FileAccess.Read), Encoding.UTF8)) {
                string line;
                while ((line = reader.ReadLine()) != null) {
                    if (line.Length == 0) continue;
                    string[] splits = line.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
                    if (splits.Length != 4) continue;
                    Stock stock = new Stock();
                    stock.Code = splits[0];
                    stock.Pinyin = splits[1];
                    stock.Name = splits[2];
                    stock.Area = splits[3];
                    stocks.Add(stock);
                }
            }

            return stocks;
        }