• R/O
  • SSH
  • HTTPS

protra: Commit


Commit MetaInfo

Revision519 (tree)
Time2014-04-14 20:51:58
Authorpanacoran

Log Message

#24665 k-db.comのサイト構成の変更に対応する

* Protra.Lib/Update/KdbComUpdator.cs (KdbComUpdator.UpdatePrice): 削除。
(KdbComUpdator.DataSince): 2007年1月4日変更する。
(KdbComUpdator.DownloadUrl): 新しいURLに対応する。
(KdbComUpdator.GetIndices): 新規。日経平均とTOPIXのデータを取得する。
(KdbComUpdator.GetMarketVolume): 古いデータを読めるようにする。途中経過を表示する。
(KdbComUpdator.InsertIndices): 新規。指数のデータを挿入する。
(KdbComUpdator.ParseLine): 指数の処理を削除する。QBoard→Q-Boardに対応する。
* Protra.Lib/Update/PriceDataUpdator.cs (PriceDataUpdator.GetDescription): k-db.comの説明を変更する。
(PriceDataUpdator.UpdatePrice): GetIndicesとInsertIndicesを呼ぶ。
(PriceDataUpdator.GetIndices): 新規。k-db.comでオーバーライドする。
(PriceDataUpdator.InsertIndices): 同上。

Change Summary

Incremental Difference

--- protra/trunk/ChangeLog.txt (revision 518)
+++ protra/trunk/ChangeLog.txt (revision 519)
@@ -1,5 +1,21 @@
11 2014-04-14 panacoran <panacoran@users.sourceforge.jp>
22
3+ #24665 k-db.comのサイト構成の変更に対応する
4+
5+ * Protra.Lib/Update/KdbComUpdator.cs (KdbComUpdator.UpdatePrice): 削除。
6+ (KdbComUpdator.DataSince): 2007年1月4日変更する。
7+ (KdbComUpdator.DownloadUrl): 新しいURLに対応する。
8+ (KdbComUpdator.GetIndices): 新規。日経平均とTOPIXのデータを取得する。
9+ (KdbComUpdator.GetMarketVolume): 古いデータを読めるようにする。途中経過を表示する。
10+ (KdbComUpdator.InsertIndices): 新規。指数のデータを挿入する。
11+ (KdbComUpdator.ParseLine): 指数の処理を削除する。QBoard→Q-Boardに対応する。
12+ * Protra.Lib/Update/PriceDataUpdator.cs (PriceDataUpdator.GetDescription): k-db.comの説明を変更する。
13+ (PriceDataUpdator.UpdatePrice): GetIndicesとInsertIndicesを呼ぶ。
14+ (PriceDataUpdator.GetIndices): 新規。k-db.comでオーバーライドする。
15+ (PriceDataUpdator.InsertIndices): 同上。
16+
17+2014-04-14 panacoran <panacoran@users.sourceforge.jp>
18+
319 PriceDataUpdatorの重複上場銘柄の処理を簡略化する
420
521 * Protra.Lib/Update/PriceDataUpdator.cs (PriceDataUpdator.UpdatePrice): 上記のとおり。
--- protra/trunk/Protra.Lib/Update/PriceDataUpdator.cs (revision 518)
+++ protra/trunk/Protra.Lib/Update/PriceDataUpdator.cs (revision 519)
@@ -394,7 +394,7 @@
394394 case PriceDataSource.Mujinzou:
395395 return "1996年からのデータを取得できます。";
396396 case PriceDataSource.KdbCom:
397- return "約二年前からのデータを取得できます。";
397+ return "2007年からのデータを取得できます。";
398398 case PriceDataSource.YahooFinance:
399399 return "1991年からのデータを取得できますが、非常に時間がかかります。";
400400 }
@@ -439,6 +439,7 @@
439439 if (!IsDataAvailable(end))
440440 end = end.AddDays(-1);
441441 _progress.NumDays = AdjustedDate(ref begin, ref end);
442+ GetIndices(worker, begin, end);
442443 _progress.Start();
443444 for (var date = begin; date <= end; date = NextDate(date))
444445 {
@@ -446,6 +447,7 @@
446447 var dl = new DownloadUtil(DownloadUrl(date));
447448 _progress.StartDownload();
448449 var prices = new SortedDictionary<string, Price>();
450+ InsertIndices(date, prices);
449451 using (var stream = dl.DownloadAndExtract())
450452 {
451453 _progress.FinishDownload();
@@ -502,6 +504,25 @@
502504 protected abstract bool IsDataAvailable(DateTime time);
503505
504506 /// <summary>
507+ /// 日経平均とTOPIXのデータを取得する(k-db.com用)。
508+ /// </summary>
509+ /// <param name="worker">BackgroundWorker</param>
510+ /// <param name="begin">最初の日付</param>
511+ /// <param name="end">最後の日付</param>
512+ protected virtual void GetIndices(BackgroundWorker worker, DateTime begin, DateTime end)
513+ {
514+ }
515+
516+ /// <summary>
517+ /// 日経平均とTOPIXのデータを挿入する。
518+ /// </summary>
519+ /// <param name="date">日付</param>
520+ /// <param name="prices">Priceのリスト</param>
521+ protected virtual void InsertIndices(DateTime date, IDictionary<string, Price> prices)
522+ {
523+ }
524+
525+ /// <summary>
505526 /// 文字列を解析して価格データを返す。
506527 /// </summary>
507528 /// <param name="line">文字列</param>
--- protra/trunk/Protra.Lib/Update/KdbComUpdator.cs (revision 518)
+++ protra/trunk/Protra.Lib/Update/KdbComUpdator.cs (revision 519)
@@ -32,34 +32,11 @@
3232 public class KdbComUpdator : PriceDataUpdator
3333 {
3434 /// <summary>
35- /// 東証一部の出来高を読んでから株価データを更新する。
36- /// </summary>
37- /// <param name="worker">BackgroundWorker</param>
38- /// <param name="e">DoWorkイベントの引数</param>
39- protected override void UpdatePrice(BackgroundWorker worker, DoWorkEventArgs e)
40- {
41- GetMarketVolume();
42- base.UpdatePrice(worker, e);
43- }
44-
45- /// <summary>
4635 /// データが存在する最初の日付を取得する。
4736 /// </summary>
4837 public override DateTime DataSince
4938 {
50- get
51- {
52- var result = DateTime.Now;
53- var date = result;
54- for (var i = 0; i < 500; date = date.AddDays(-1))
55- {
56- if (!Calendar.IsMarketOpen(date))
57- continue;
58- result = date;
59- i++;
60- }
61- return new DateTime(result.Year, result.Month, result.Day);
62- }
39+ get { return new DateTime(2007, 1, 4); }
6340 }
6441
6542 /// <summary>
@@ -78,38 +55,120 @@
7855 /// <returns>URL</returns>
7956 protected override string DownloadUrl(DateTime date)
8057 {
81- return "http://k-db.com/site/download.aspx?p=all&download=csv&date=" + date.ToString("yyyy-MM-dd");
58+ return string.Format("http://k-db.com/stocks/{0:yyyy-MM-dd}?download=csv", date);
8259 }
8360
84- private Dictionary<DateTime, double> _indexVolume;
61+ private readonly Dictionary<DateTime, double> _marketVolume = new Dictionary<DateTime, double>();
62+ private readonly Dictionary<DateTime, Price> _nikkei225 = new Dictionary<DateTime, Price>();
63+ private readonly Dictionary<DateTime, Price> _topix = new Dictionary<DateTime, Price>();
8564
86- private void GetMarketVolume()
65+ /// <summary>
66+ /// 日経平均とTOPIXのデータを取得する。
67+ /// </summary>
68+ /// <param name="worker">BackgroundWorker</param>
69+ /// <param name="begin">最初の日付</param>
70+ /// <param name="end">最後の日付</param>
71+ protected override void GetIndices(BackgroundWorker worker, DateTime begin, DateTime end)
8772 {
88- _indexVolume = new Dictionary<DateTime, double>();
89- var dl = new DownloadUtil("http://k-db.com/site/toukei.aspx?market=T1&download=csv");
90- var stream = dl.GetResponse();
91- if (stream == null)
92- throw new ApplicationException("市場統計データの読み込みに失敗しました。");
93- using (var reader = new StreamReader(stream, Encoding.GetEncoding("shift_jis")))
73+ GetMarketVolume(worker, begin, end);
74+ GetIndexValues(worker, begin, end);
75+ }
76+
77+ private void GetMarketVolume(BackgroundWorker worker, DateTime begin, DateTime end)
78+ {
79+ for (var year = begin.Year; year <= end.Year; year++)
9480 {
95- string line;
96- while ((line = reader.ReadLine()) != null)
81+ var span = end.Year - begin.Year;
82+ worker.ReportProgress(span == 0 ? 0 : (year - begin.Year) * 100 / span,
83+ string.Format("市場統計: {0:D}年", year));
84+ var dl = new DownloadUtil(string.Format("http://k-db.com/statistics/T1?year={0:D}&download=csv", year));
85+ var stream = dl.GetResponse();
86+ if (stream == null)
87+ throw new ApplicationException("市場統計データの読み込みに失敗しました。");
88+ using (var reader = new StreamReader(stream, Encoding.GetEncoding("shift_jis")))
9789 {
98- var tokens = line.Split(',');
99- switch (tokens[0])
90+ string line;
91+ while ((line = reader.ReadLine()) != null)
10092 {
101- case "東証1部":
102- case "日付":
103- continue;
93+ var tokens = line.Split(',');
94+ switch (tokens[0])
95+ {
96+ case "東証1部":
97+ case "日付":
98+ continue;
99+ }
100+ try
101+ {
102+ var date = DateTime.Parse(tokens[0]);
103+ var volume = Math.Round(double.Parse(tokens[1]) / 1000); // 無尽蔵に合わせるため丸める。
104+ _marketVolume[date] = volume;
105+ }
106+ catch (FormatException e)
107+ {
108+ throw new ApplicationException("市場統計データの読み込みに失敗しました:\r\n" + e.Message);
109+ }
104110 }
105- var date = DateTime.Parse(tokens[0]);
106- var volume = Math.Round(double.Parse(tokens[1]) / 1000); // 無尽蔵に合わせるため丸める。
107- _indexVolume[date] = volume;
108111 }
109112 }
113+ worker.ReportProgress(100, "");
110114 }
111115
116+ private void GetIndexValues(BackgroundWorker worker, DateTime begin, DateTime end)
117+ {
118+ for (var year = begin.Year; year <= end.Year; year++)
119+ {
120+ var span = end.Year - begin.Year;
121+ worker.ReportProgress(span == 0 ? 0 : (year - begin.Year) * 100 / span,
122+ string.Format("指数: {0:D}年", year));
123+ foreach (var kdbCode in new[] {"I101", "I102"})
124+ {
125+ var dl = new DownloadUtil(string.Format(
126+ "http://k-db.com/indices/{0}?year={1:D}&download=csv", kdbCode, year));
127+ var stream = dl.GetResponse();
128+ if (stream == null)
129+ throw new ApplicationException("指数の読み込みに失敗しました。");
130+ var prices = kdbCode == "I101" ? _nikkei225 : _topix;
131+ var code = kdbCode == "I101" ? "1001" : "1002";
132+ using (var reader = new StreamReader(stream, Encoding.GetEncoding("shift_jis")))
133+ {
134+ string line;
135+ while ((line = reader.ReadLine()) != null)
136+ {
137+ var tokens = line.Split(',');
138+ if (tokens.Length != 5)
139+ continue;
140+ if (tokens[0] == "日付")
141+ continue;
142+ var date = DateTime.Parse(tokens[0]);
143+ prices[date] = new Price
144+ {
145+ Date = date,
146+ Code = code,
147+ Open = (int)double.Parse(tokens[1]),
148+ High = (int)double.Parse(tokens[2]),
149+ Low = (int)double.Parse(tokens[3]),
150+ Close = (int)double.Parse(tokens[4]),
151+ Volume = _marketVolume[date]
152+ };
153+ }
154+ }
155+ }
156+ }
157+ worker.ReportProgress(100, "");
158+ }
159+
112160 /// <summary>
161+ /// 日経平均とTOPIXのデータを挿入する。
162+ /// </summary>
163+ /// <param name="date">日付</param>
164+ /// <param name="prices">Priceのリスト</param>
165+ protected override void InsertIndices(DateTime date, IDictionary<string, Price> prices)
166+ {
167+ prices.Add(_nikkei225[date].Code, _nikkei225[date]);
168+ prices.Add(_topix[date].Code, _topix[date]);
169+ }
170+
171+ /// <summary>
113172 /// 文字列に含まれるデータを格納したオブジェクトを返す。
114173 /// </summary>
115174 /// <param name="line">文字列を指定する。</param>
@@ -121,73 +180,66 @@
121180 var r = new Price();
122181 try
123182 {
124- if (tokens[0] == "10" || tokens[0] == "67")
183+ if (tokens.Length != 10 || tokens[0].Length != 6)
184+ return null;
185+ r.Code = tokens[0].Substring(0, 4);
186+ switch (tokens[1])
125187 {
126- r.Code = tokens[0] == "67" ? "1001" : "1002";
127- r.Market = "T1";
128- r.Volume = _indexVolume[date];
188+ case "市場":
189+ return null;
190+ case "東証":
191+ case "東証1部":
192+ r.Market = "T1";
193+ break;
194+ case "東証2部":
195+ r.Market = "T2";
196+ break;
197+ case "東証マザーズ":
198+ case "東証マザーズ外国":
199+ r.Market = "M";
200+ break;
201+ case "東証TPM":
202+ return null;
203+ case "東証1部外国":
204+ r.Market = "T1";
205+ break;
206+ case "大証":
207+ case "大証1部":
208+ r.Market = "O1";
209+ break;
210+ case "大証2部":
211+ r.Market = "O2";
212+ break;
213+ case "東証JQグロース":
214+ case "東証JQスタンダード":
215+ case "東証JQスタンダード外国":
216+ case "JQ":
217+ case "JQスタンダード":
218+ case "JQスタンダード外国":
219+ case "JQグロース":
220+ case "JQNEO":
221+ r.Market = "J";
222+ break;
223+ case "HCスタンダード":
224+ case "HCスタンダード外国":
225+ case "HCグロース":
226+ r.Market = "H";
227+ break;
228+ case "福証":
229+ case "福証Q-Board":
230+ case "札証":
231+ case "札証アンビシャス":
232+ case "名証":
233+ return null;
234+ default:
235+ throw new ApplicationException(tokens[1] + ": 不明な市場名です。");
129236 }
130- else if (tokens[0].Length == 6)
131- {
132- r.Code = tokens[0].Substring(0, 4);
133- switch (tokens[2])
134- {
135- case "東証":
136- case "東証1部":
137- r.Market = "T1";
138- break;
139- case "東証2部":
140- r.Market = "T2";
141- break;
142- case "東証マザーズ":
143- case "東証マザーズ外国":
144- r.Market = "M";
145- break;
146- case "東証TPM":
147- return null;
148- case "東証1部外国":
149- r.Market = "T1";
150- break;
151- case "大証":
152- case "大証1部":
153- r.Market = "O1";
154- break;
155- case "大証2部":
156- r.Market = "O2";
157- break;
158- case "東証JQグロース":
159- case "東証JQスタンダード":
160- case "東証JQスタンダード外国":
161- case "JQ":
162- case "JQスタンダード":
163- case "JQスタンダード外国":
164- case "JQグロース":
165- case "JQNEO":
166- r.Market = "J";
167- break;
168- case "HCスタンダード":
169- case "HCスタンダード外国":
170- case "HCグロース":
171- r.Market = "H";
172- break;
173- case "福証":
174- case "福証QBoard":
175- case "札証":
176- case "札証アンビシャス":
177- case "名証":
178- return null;
179- default:
180- throw new ApplicationException(tokens[2] + ": 不明な市場名です。");
181- }
182- r.Volume = ParseField(tokens[8]) / 1000;
183- }
184- else
185- return null;
186237 r.Date = date;
187238 r.Open = (int)ParseField(tokens[4]);
188239 r.High = (int)ParseField(tokens[5]);
189240 r.Low = (int)ParseField(tokens[6]);
190241 r.Close = (int)ParseField(tokens[7]);
242+ r.Volume = ParseField(tokens[8]) / 1000;
191243 }
192244 catch (FormatException)
193245 {
Show on old repository browser