private void btnTest_Click(object sender, EventArgs e) { MyStockAnalyzer.Classes.StockData data = model.GetStockDataById("3086"); List <MyStockAnalyzer.Classes.StockPrice> result = stockHelper.GetStockRealTimePrice(new List <MyStockAnalyzer.Classes.StockData>() { data }, DateTime.Now.Date); }
/// <summary> /// 執行下載股價資訊執行緒 /// </summary> /// <param name="obj"></param> private void threadDownloadStockPrice_Start(object obj) { if (obj is MyStockAnalyzer.Classes.StockData) { MyStockAnalyzer.Classes.StockData stock = obj as MyStockAnalyzer.Classes.StockData; List <MyStockAnalyzer.Classes.StockPrice> singleStockPrices = stockHelper.GetStockPriceDataList(stock, dtStockBgn.Value.Date, dtStockEnd.Value.Date); lock (this) { waitedUpdateSotckPrice.AddRange(singleStockPrices); } } }
/// <summary> /// 下載股價資訊 /// </summary> /// <param name="stock"></param> /// <param name="bgnDate"></param> /// <param name="endDate"></param> /// <returns></returns> public List <MyStockAnalyzer.Classes.StockPrice> GetStockPriceDataList(MyStockAnalyzer.Classes.StockData stock, DateTime bgnDate, DateTime endDate) { List <MyStockAnalyzer.Classes.StockPrice> result = new List <MyStockAnalyzer.Classes.StockPrice>(); // 列舉每個月分出來 for (DateTime fetchDate = bgnDate; fetchDate <= endDate; fetchDate = fetchDate.AddMonths(1)) { // 抓取股票價格 List <MyStockAnalyzer.Classes.StockPrice> stockPrices = downloadStockPriceData(stock, fetchDate, stock.Class == "上市" ? "1" : "2"); result.AddRange(stockPrices.Where(s => s.Date >= bgnDate && s.Date <= endDate)); } return(result); }
/// <summary> /// 下載股價資訊 /// </summary> /// <param name="stock"></param> /// <param name="bgnDate"></param> /// <param name="endDate"></param> /// <returns></returns> public List<StockPrice> GetStockPriceDataList(StockData stock, DateTime bgnDate, DateTime endDate) { List<MyStockAnalyzer.Classes.StockPrice> result = new List<MyStockAnalyzer.Classes.StockPrice>(); // 列舉每個月分出來 for (DateTime fetchDate = bgnDate; fetchDate <= endDate; fetchDate = fetchDate.AddMonths(1)) { // 抓取股票價格 List<MyStockAnalyzer.Classes.StockPrice> stockPrices = downloadStockPriceData(stock, fetchDate, stock.Class == "上市" ? "1" : "2"); result.AddRange(stockPrices.Where(s => s.Date >= bgnDate && s.Date <= endDate)); } return result; }
private void selectStockByAlgorithms(MyStockAnalyzer.Classes.StockData data, List <StockChartData> chartData) { foreach (IStockSelectionAlgorithm algorithm in this.stockSelectionAlgorithms) { // 當演算法指定只檢查權證標的時, 忽略非權證標的個股 if (skipIfAlgorithmWarrantOnlyAndStockWithoutWarrant(algorithm, data)) { continue; } List <StockSelectionResult> result = algorithm.GetSelectionResult(chartData, dtSelectionBgn.Value.Date, dtSelectionEnd.Value.Date.AddDays(1).AddSeconds(-1)); foreach (StockSelectionResult ss in result) { dgvSelectionResult.Rows.Add(new string[] { ss.Date.ToString("yyyy/MM/dd"), data.StockId, data.StockName, algorithm.Name, data.WarrantTarget, ss.Memo }); } } }
/// <summary> /// 下載股票名稱資訊 /// </summary> /// <param name="url"></param> /// <returns></returns> private List<StockData> downloadStockDataList(string url) { List<StockData> result = new List<StockData>(); WebClient wc = new WebClient(); string text = wc.DownloadString(url); string[] data = text.Split(new string[] { "</table>" }, StringSplitOptions.RemoveEmptyEntries); string dataListText = HtmlRemovalHelper.StripTagsCharArray(data[1].Replace("</tr>", "[NR]</tr>").Replace("</td>", "[TAB]")); string[] dataList = dataListText.Split(new string[] { "[NR]" }, StringSplitOptions.RemoveEmptyEntries); string currentType = ""; foreach (string line in dataList.Skip(1)) { string[] fields = line.Split(new string[] { "[TAB]" }, StringSplitOptions.RemoveEmptyEntries); if (fields.Count() == 1) { if (line.Contains("股票") || line.Contains("ETF")) { currentType = fields[0].Trim(); } else { currentType = ""; } } else if(!String.IsNullOrEmpty(currentType)) { string[] fields2 = line.Split(new string[] { "[TAB]" }, StringSplitOptions.None); StockData stockData = new StockData(); stockData.StockId = fields2[0].Split(new string[] { " ", "\t", " " }, StringSplitOptions.None).First(); stockData.StockName = fields2[0].Split(new string[] { " ", "\t", " " }, StringSplitOptions.None).Last(); stockData.Class = fields2[3]; stockData.Industry = String.IsNullOrEmpty(fields2[4]) ? currentType : fields2[4]; result.Add(stockData); } } return result; }
/// <summary> /// 從網路直接下載上市櫃股票價格檔並解析 /// </summary> /// <param name="stock"></param> /// <param name="fetchDate"></param> /// <param name="type">1: 上市, 2: 上櫃</param> /// <returns></returns> private List <MyStockAnalyzer.Classes.StockPrice> downloadStockPriceData(MyStockAnalyzer.Classes.StockData stock, DateTime fetchDate, string type) { List <MyStockAnalyzer.Classes.StockPrice> result = new List <MyStockAnalyzer.Classes.StockPrice>(); string downloadUrl = String.Format(type == "1" ? ConfigHelper.StockPriceUrl1 : ConfigHelper.StockPriceUrl2, type == "1" ? fetchDate.Year.ToString() : (fetchDate.Year - 1911).ToString("000"), fetchDate.Month.ToString("00"), stock.StockId); WebClient wc = getNewWebClient(); string csvText = wc.DownloadString(downloadUrl); string[] lines = csvText.Split(new string[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (string line in lines.Skip(type == "1" ? 2 : 5)) { // 上櫃檔案最後一行跳過 if (type == "2" && line.Equals(lines.Last())) { continue; } string[] fields = CSVHelper.ParseCSVLine(line, ","); if (fields.Length == 9) { if (fields[3].Equals("--") || fields[4].Equals("--") || fields[5].Equals("--") || fields[6].Equals("--")) { continue; } string[] strDate = (fields[0].Trim().StartsWith("1") ? fields[0].Trim().Substring(0, 9) : fields[0].Trim().Substring(0, 8)).Split(new string[] { "/" }, StringSplitOptions.None); int year = Convert.ToInt32(strDate[0]); if (year < 1000) { year += 1911; } DateTime date = new DateTime(year, Convert.ToInt32(strDate[1]), Convert.ToInt32(strDate[2])); // date = date.AddYears(1911); StockPrice priceData = new StockPrice(); priceData.StockId = stock.StockId; priceData.Date = date; int amount = Convert.ToInt32(fields[1].Replace(",", "")); if (amount != 0) { if (type == "1") { priceData.Amount = amount / 1000; } else if (type == "2") // 上櫃欄位直接是千股 { priceData.Amount = amount; } priceData.Open = Convert.ToDecimal(fields[3].Replace(",", "")); priceData.High = Convert.ToDecimal(fields[4].Replace(",", "")); priceData.Low = Convert.ToDecimal(fields[5].Replace(",", "")); priceData.Close = Convert.ToDecimal(fields[6].Replace(",", "")); result.Add(priceData); } } } return(result); }
private bool skipIfAlgorithmWarrantOnlyAndStockWithoutWarrant(IStockSelectionAlgorithm algorithm, MyStockAnalyzer.Classes.StockData stockData) { if (algorithm is IStockSelectionConditionWarrantOnly) { if (stockData.WarrantTarget == null || !stockData.WarrantTarget.Equals("Y")) { return(true); } } return(false); }