分級基金折溢價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