using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; using System.Collections; using NDde.Client; using Zanetti.Data; namespace Zanetti.DataSource.Specialized { internal class RakuteRssDataSource : DailyDataSource { private const int MAXRETRYCOUNT = 3; public RakuteRssDataSource(int[] dates) : base(dates) { } public override void Run() { DateTime ld = Util.GuessLatestTradeDate(); var date = int.Parse(ld.ToString("yyyyMMdd")); //if (!ChkRss(_dates[_dates.Length - 1])) if (!ChkRss(date)) { //RSSが動いてない旨、メッセージを出したいけどわからない //SendMessage(AsyncConst.WM_ASYNCPROCESS, 0, AsyncConst.LPARAM_ERROR); System.Windows.Forms.MessageBox.Show("楽天RSSが起動していません。","エラー", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); return; } GetIndices(); // 先に指数のデータを読む。 var newdata = new Dictionary>(); newdata[date] = FillData(date); SendMessage(AsyncConst.WM_ASYNCPROCESS, date | DATE_MASK, AsyncConst.LPARAM_PROGRESS_SUCCESSFUL); foreach (AbstractBrand br in Env.BrandCollection.Values) { if (br.Market == MarketType.B && !IsSupportedIndex(br.Code) || br.Market == MarketType.Custom) continue; using (var farm = (DailyDataFarm)br.CreateDailyFarm(_dates.Length)) { var traceFlag = false; NewDailyData td; if (newdata[date].TryGetValue(br.Code, out td)) { farm.UpdateDataFarm(date, td); } else { if (traceFlag) continue; traceFlag = true; Debug.WriteLine("Data not found(RakutenRSS) : code=" + br.Code + " market=" + br.Market); } farm.Save(Util.GetDailyDataFileName(br.Code)); SendMessage(AsyncConst.WM_ASYNCPROCESS, br.Code, AsyncConst.LPARAM_PROGRESS_SUCCESSFUL); } } } private readonly Dictionary _marketVolume = new Dictionary(); private readonly Dictionary _nikkei225 = new Dictionary(); private readonly Dictionary _topix = new Dictionary(); //private readonly Dictionary _mothers = new Dictionary(); private readonly Dictionary _jasdaq = new Dictionary(); private void GetIndices() { GetMarketVolume(); GetIndexValues(); } private void GetMarketVolume() { var date = DateTime.Parse(GetRssReturnString("TV1", "現在日付")); var volume = double.Parse(GetRssReturnString("TV1", "出来高")); _marketVolume[date] = (int)(volume * 100);//楽天RSS、東証一部出来高は1万株の桁から } private void GetIndexValues() { //foreach (var code in new[] { "N225", "TOPX", "MTHR", "JSD" }) foreach (var code in new[] { "N225", "TOPX", "JSD" }) { //var prices = code == "N225" ? _nikkei225 : code == "TOPX" ? _topix : code == "MTHR" ? _mothers : _jasdaq; var prices = code == "N225" ? _nikkei225 : code == "TOPX" ? _topix : _jasdaq; var date = DateTime.Parse(GetRssReturnString(code, "現在日付")); prices[date] = new NewDailyData { open = (int)(double.Parse(GetRssReturnString(code, "始値")) * 100), high = (int)(double.Parse(GetRssReturnString(code, "高値")) * 100), low = (int)(double.Parse(GetRssReturnString(code, "安値")) * 100), close = (int)(double.Parse(GetRssReturnString(code, "現在値")) * 100), volume = _marketVolume[date] }; } } private void InsertIndices(DateTime date, Dictionary result) { result[(int)BuiltInIndex.Nikkei225] = _nikkei225[date]; result[(int)BuiltInIndex.TOPIX] = _topix[date]; //result[(int)BuiltInIndex.MOTHERS] = _mothers[date]; result[(int)BuiltInIndex.JASDAQ] = _jasdaq[date]; } private class BrandComparer : IComparer { public int Compare(object x, object y) { return ((AbstractBrand)x).Code - ((AbstractBrand)y).Code; } } private Dictionary FillData(int date) { var result = new Dictionary(); var d2 = Util.IntToDate(date); InsertIndices(d2, result); ArrayList ar = new ArrayList(Env.BrandCollection.Values); ar.Sort(new BrandComparer()); foreach (AbstractBrand br in ar) { var basic = br as BasicBrand; if (basic == null || basic.Market == MarketType.B || basic.Market == MarketType.Custom || basic.Obsolete == true) continue; var cnt = 0; var op = string.Empty; var hi = string.Empty; var lo = string.Empty; var cl = string.Empty; var vo = string.Empty; while (!set_value(br.Code, ref op, ref hi, ref lo, ref cl, ref vo)) { cnt++; if (cnt >= MAXRETRYCOUNT) break; } //存在しなかった銘柄 if (op == null || hi == null || lo == null || cl == null || vo == null) continue; //出来高がなかった銘柄 else if (op.Trim() == string.Empty || hi.Trim() == string.Empty || lo.Trim() == string.Empty || cl.Trim() == string.Empty || vo.Trim() == "0") continue; const double shift = 10; // 株価は10倍で記録 try { result[br.Code] = new NewDailyData { open = int.Parse((double.Parse(op) * shift).ToString()), high = int.Parse((double.Parse(hi) * shift).ToString()), low = int.Parse((double.Parse(lo) * shift).ToString()), close = int.Parse((double.Parse(cl) * shift).ToString()), volume = int.Parse((double.Parse(vo)).ToString()) }; } catch (Exception ex) { Console.WriteLine(ex.Message); } SendMessage(AsyncConst.WM_ASYNCPROCESS, br.Code, AsyncConst.LPARAM_PROGRESS_SUCCESSFUL); } return result; } private bool set_value(object code, ref string op, ref string hi, ref string lo, ref string cl, ref string vo) { op = GetRssReturnString(code + ".T", "始値"); hi = GetRssReturnString(code + ".T", "高値"); lo = GetRssReturnString(code + ".T", "安値"); cl = GetRssReturnString(code + ".T", "現在値"); vo = GetRssReturnString(code + ".T", "出来高"); //存在しない銘柄コードを入れるとnullが返る if (op == null || hi == null || lo == null || cl == null || vo == null) { System.Threading.Thread.Sleep(1000); return false; } else return true; } private string GetRssReturnString(object code, string syubetu) { byte[] data = null; string ret = null; NDde.Client.DdeClient client = null; try { client = new DdeClient("RSS", string.Format("{0}", code)); client.Connect(); data = client.Request(syubetu, 1, 1000); ret = Encoding.Default.GetString(data).Replace("\0", ""); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { if (client != null) client.Dispose(); } return ret; } private bool ChkRss(int date) { NDde.Client.DdeClient client = null; bool ret = true; try { client = new DdeClient("RSS", "N225"); client.Connect(); byte[] data = client.Request("現在日付", 1, 1000); } catch (Exception ex) { Console.WriteLine(ex.Message); ret = false; } finally { if (client != null) client.Dispose(); } return ret; } private bool IsSupportedIndex(int code) { return code == (int)BuiltInIndex.Nikkei225 || code == (int)BuiltInIndex.TOPIX || //code == (int)BuiltInIndex.MOTHERS || code == (int)BuiltInIndex.JASDAQ; } } }