分級基金折溢價WinForm網絡計算器
通過子/母基金代碼,從 [ 東方財富網,天天基金網,新浪 ] 抓取分級基金的子母基金數據(代碼,名稱,淨值,價格),
並計算出子基金(A基金,B基金)以及母基金的溢價率與折價率,
便於投資/投機客從中套利。
數據通過網站獲取,使用基金淨值,非估值,一般晚間網站會更新當天基金淨值,不可用於實時計算。
------
效果圖:
----
代碼:
1.窗體如效果圖
2.常用變量與數據抓取代碼:
1 namespace fundGetAndCal 2 { 3 public static class CONST 4 { 5 //獲取母子基金代碼 6 public static string fundF10Url = "http://fund.eastmoney.com/f10/jbgk_{%fundCode%}.html"; 7 //獲取淨值 8 public static string fundValUrl = "http://fund.eastmoney.com/{%fundCode%}.html"; 9 //獲取價格 10 public static string fundPriceUrl = "http://hq.sinajs.cn/?list={%fundAllCode%}"; 11 //母子基金列表 12 public static List<string[]> allFunCodeLst; 13 //讀取完了 14 public static bool okFlg = false; 15 //狀態顯示文字 16 public static string show = "就緒"; 17 public static int barMax = 100; 18 public static int barNow = 100; 19 20 public static string GetHtml(string url, Encoding encode) 21 { 22 string strBuff = "";//定義文本字符串,用來保存下載的html 23 try 24 { 25 HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url); 26 HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse(); 27 //若成功取得網頁的內容,則以System.IO.Stream形式返回,若失敗則產生ProtoclViolationException錯 誤。在此正確的做法應將以下的代碼放到一個try塊中處理。這裡簡單處理 28 Stream reader = webResponse.GetResponseStream(); 29 ///返回的內容是Stream形式的,所以可以利用StreamReader類獲取GetResponseStream的內容,並以StreamReader類的Read方法依次讀取網頁源程序代碼每一行的內容,直至行尾(讀取的編碼格式:UTF8) 30 StreamReader respStreamReader = new StreamReader(reader,/*Encoding.UTF8*/encode); 31 32 strBuff = respStreamReader.ReadToEnd(); 33 } 34 catch (Exception e) 35 { 36 Console.Write(url+"\n"+e.Message); 37 } 38 return strBuff; 39 } 40 } 41 }
3.窗體按鈕等事件代碼:
1 namespace fundGetAndCal 2 { 3 public partial class Form1 : Form 4 { 5 public Form1() 6 { 7 InitializeComponent(); 8 } 9 10 private void Form1_Load(object sender, EventArgs e) 11 { 12 getFundCode(); 13 } 14 private void btnFundCodeRead_Click(object sender, EventArgs e) 15 { 16 getFundCode(); 17 } 18 private void getFundCode() 19 { 20 string waitFuncCodes = ConfigurationManager.AppSettings.Get("fundCode"); 21 waitFuncCodes = waitFuncCodes.Replace(",", "\r\n"); 22 fundCodeLst.Text = waitFuncCodes; 23 } 24 private string delStr(string org, string other) 25 { 26 if (!other.Equals("")) 27 org = org.Replace(other, ""); 28 return Regex.Replace(org, @"<.*?>", ""); 29 } 30 private void btnStart_Click(object sender, EventArgs e) 31 { 32 Thread thread = new Thread(getData); 33 thread.IsBackground = true; 34 CONST.barMax = 100; 35 CONST.barNow = 0; 36 37 btnStart.Enabled = false; 38 btnStop.Enabled = true; 39 CONST.okFlg = false; 40 41 thread.Start(); 42 timer1.Start(); 43 } 44 45 private void getData() 46 { 47 /// 提取母子基金代碼 48 49 // 提取母基金正則 50 Regex regMJJ = new Regex(@"母子基金.*?<\/td>"); 51 // 提取基金淨值正則 52 Regex regJZ = new Regex(@"<span class=\'left12\'>.*?<\/span>"); 53 // 提取基金名稱正則 54 Regex regMC = new Regex(@"<title.*?<\/title>"); 55 string[] fcl = fundCodeLst.Text.Replace("\r\n", ",").Split(','); 56 List<string[]> allFCLst = new List<string[]>(); 57 List<string> geted = new List<string>(); 58 59 foreach (string fc in fcl) 60 { 61 CONST.show = "開始獲取[" + fc + "]子母基金代碼"; 62 if (geted.Contains(fc.Substring(2, fc.Length - 2))) 63 continue; 64 string html = CONST.GetHtml(CONST.fundF10Url.Replace("{%fundCode%}", fc.Substring(2, fc.Length - 2)), Encoding.GetEncoding("gb2312")); 65 66 var result = regMJJ.Match(html).Groups; 67 if (result.Count > 0) 68 { 69 // 1-3 代碼,4-6 淨值 7-9 價格 10 sz/ss 11-13 名稱 70 string[] allFC = new string[13] { "", "", "", "", "", "", "", "", "", "", "", "", "" }; 71 var r = delStr(result[0].Value, "母子基金"); 72 string[] t1 = Regex.Split(r, "(母)", RegexOptions.IgnoreCase); 73 geted.Add(t1[0]); 74 allFC[0] = t1[0]; 75 if (t1.Length > 1) 76 { 77 string[] t2 = t1[1].Split(' '); 78 for (int i = 0; i < t2.Length; i++) 79 { 80 geted.Add(t2[i].Replace("(子)", "")); 81 allFC[i + 1] = t2[i].Replace("(子)", ""); 82 } 83 if (t2.Length == 2) 84 { 85 allFC[9] = fc.Substring(0, 2); 86 allFCLst.Add(allFC); 87 } 88 } 89 } 90 //Thread.Sleep(1000); 91 } 92 CONST.barNow = CONST.barNow + (int)Math.Floor((decimal)CONST.barMax / 3); 93 CONST.allFunCodeLst = allFCLst; 94 95 // 獲取淨值,名稱 96 foreach (string[] allFC in CONST.allFunCodeLst) 97 { 98 for (int i = 0; i < 3; i++) 99 { 100 CONST.show = "開始獲取[" + allFC[i] + "]淨值與名稱"; 101 string html = CONST.GetHtml(CONST.fundValUrl.Replace("{%fundCode%}", allFC[i]), Encoding.GetEncoding("gb2312")); 102 103 var result = regJZ.Match(html).Groups; 104 if (result.Count > 0) 105 { 106 allFC[3 + i] = delStr(result[0].Value, ""); 107 } 108 result = regMC.Match(html).Groups; 109 string[] a = delStr(result[0].Value, "").Split('('); 110 if (a.Length > 0) 111 { 112 allFC[10 + i] = a[0]; 113 } 114 115 //Thread.Sleep(1000); 116 } 117 } 118 CONST.barNow = CONST.barNow + (int)Math.Floor((decimal)CONST.barMax / 3); 119 120 // 獲取價格 121 foreach (string[] allFC in CONST.allFunCodeLst) 122 { 123 for (int i = 1; i < 3; i++) 124 { 125 CONST.show = "開始獲取[" + allFC[i] + "]價格"; 126 string html = CONST.GetHtml(CONST.fundPriceUrl.Replace("{%fundAllCode%}", allFC[9] + allFC[i]), Encoding.GetEncoding("gb2312")); 127 128 string[] result = html.Split(','); 129 if (result.Length > 4) 130 { 131 allFC[6 + i] = result[3]; 132 } 133 //Thread.Sleep(1000); 134 } 135 } 136 CONST.barNow = CONST.barNow + (int)Math.Floor((decimal)CONST.barMax / 3); 137 CONST.okFlg = true; 138 139 } 140 141 private void timer1_Tick(object sender, EventArgs e) 142 { 143 if (CONST.okFlg) 144 { 145 CONST.show = "開始獲取計算溢折價,並輸出"; 146 // 計算A,B基金溢折價,母基金溢折價 147 dataGridView1.Rows.Clear(); 148 dataGridView1.Columns.Clear(); 149 dataGridView1.Columns.Add("code1", "母代碼"); 150 dataGridView1.Columns.Add("name1", "母名稱"); 151 dataGridView1.Columns.Add("val1", "母淨值"); 152 dataGridView1.Columns.Add("yzj1", "母溢折價"); 153 dataGridView1.Columns.Add("code2", "A代碼"); 154 dataGridView1.Columns.Add("name2", "A名稱"); 155 dataGridView1.Columns.Add("val2", "A淨值"); 156 dataGridView1.Columns.Add("price2", "A價格"); 157 dataGridView1.Columns.Add("yzj2", "A溢折價"); 158 dataGridView1.Columns.Add("code3", "B代碼"); 159 dataGridView1.Columns.Add("name3", "B名稱"); 160 dataGridView1.Columns.Add("val3", "B淨值"); 161 dataGridView1.Columns.Add("price3", "B價格"); 162 dataGridView1.Columns.Add("yzj3", "B溢折價"); 163 foreach (string[] allFC in CONST.allFunCodeLst) 164 { 165 DataGridViewRow dgvr = new DataGridViewRow(); 166 dataGridView1.Rows.Add(dgvr); 167 dgvr = dataGridView1.Rows[dataGridView1.Rows.Count - 1]; 168 dgvr.Cells["code1"].Value = allFC[0]; 169 dgvr.Cells["code2"].Value = allFC[1]; 170 dgvr.Cells["code3"].Value = allFC[2]; 171 dgvr.Cells["name1"].Value = allFC[10]; 172 dgvr.Cells["name2"].Value = allFC[11]; 173 dgvr.Cells["name3"].Value = allFC[12]; 174 dgvr.Cells["val1"].Value = allFC[3]; 175 dgvr.Cells["val2"].Value = allFC[4]; 176 dgvr.Cells["val3"].Value = allFC[5]; 177 dgvr.Cells["price2"].Value = allFC[7]; 178 dgvr.Cells["price3"].Value = allFC[8]; 179 if (allFC[7] != "" && allFC[8] != "") 180 { 181 dgvr.Cells["yzj1"].Value = Math.Round(( 182 (double.Parse(allFC[7]) + double.Parse(allFC[8])) * 0.5 - double.Parse(allFC[3])) / double.Parse(allFC[3]) * 100, 2) + "%"; ; 183 dgvr.Cells["yzj2"].Value = Math.Round((double.Parse(allFC[7]) - double.Parse(allFC[4])) / double.Parse(allFC[4]) * 100, 2) + "%"; 184 dgvr.Cells["yzj3"].Value = Math.Round((double.Parse(allFC[8]) - double.Parse(allFC[5])) / double.Parse(allFC[5]) * 100, 2) + "%"; 185 186 if (dgvr.Cells["yzj1"].Value.ToString().StartsWith("-")) 187 { 188 dgvr.Cells["yzj1"].Style.ForeColor = Color.Green; 189 } 190 else 191 { 192 dgvr.Cells["yzj1"].Style.ForeColor = Color.Red; 193 } 194 if (dgvr.Cells["yzj2"].Value.ToString().StartsWith("-")) 195 { 196 dgvr.Cells["yzj2"].Style.ForeColor = Color.Green; 197 } 198 else 199 { 200 dgvr.Cells["yzj2"].Style.ForeColor = Color.Red; 201 } 202 if (dgvr.Cells["yzj3"].Value.ToString().StartsWith("-")) 203 { 204 dgvr.Cells["yzj3"].Style.ForeColor = Color.Green; 205 } 206 else 207 { 208 dgvr.Cells["yzj3"].Style.ForeColor = Color.Red; 209 } 210 } 211 } 212 StatusLabel.Text = "就緒"; 213 ProgressBar.Value = CONST.barMax; 214 CONST.okFlg = false; 215 timer1.Stop(); 216 btnStart.Enabled = true; 217 btnStop.Enabled = false; 218 } 219 else 220 { 221 StatusLabel.Text = CONST.show; 222 ProgressBar.Maximum = CONST.barMax; 223 ProgressBar.Value = CONST.barNow > CONST.barMax ? CONST.barMax : CONST.barNow; 224 } 225 } 226 227 private void btnFundCodeSave_Click(object sender, EventArgs e) 228 { 229 // 寫入參數設置 230 string fundCode = fundCodeLst.Text.Replace("\r\n", ","); 231 Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 232 configuration.AppSettings.Settings["fundCode"].Value = fundCode; 233 configuration.Save(ConfigurationSaveMode.Modified); 234 ConfigurationManager.RefreshSection("appSettings"); 235 MessageBox.Show("保存成功"); 236 } 237 238 private void dataGridView1_SortCompare(object sender, DataGridViewSortCompareEventArgs e) 239 { 240 if (e.Column.HeaderText.EndsWith("溢折價")) 241 { 242 // 按數字排序 243 if (e.CellValue1 == null || "".equals(e.CellValue1))//附件此處有錯 244 { 245 e.SortResult = -1;//附件此處有錯 246 } 247 else if (e.CellValue2 == null || "".equals(e.CellValue2))//附件此處有錯 248 { 249 e.SortResult = 1;//附件此處有錯 250 } 251 else 252 { 253 e.SortResult = double.Parse(e.CellValue1.ToString().Replace("%", "")) - double.Parse(e.CellValue1.ToString().Replace("%", "")) > 0 ? 1 : double.Parse(e.CellValue1.ToString().Replace("%", "")) - double.Parse(e.CellValue1.ToString().Replace("%", "")) < 0 ? -1 : 0;//附件此處有錯 254 } 255 } 256 else 257 { 258 // 按字符串排序 259 e.SortResult = String.Compare(Convert.ToString(e.CellValue1), Convert.ToString(e.CellValue2)); 260 }e.Handled = true;//附件此處有錯,如此才能反映到winform上去 261 } 262 } 263 }
---
源碼及程序下載地址:
http://download.csdn.net/detail/wangxsh42/8754241