- using System;
- using System.IO;
- using System.Collections.Generic;
- using System.Windows.Forms;
- using Zanetti.Commands;
- namespace Zanetti.Data
- {
- internal abstract class DataImporter
- {
- private const int SHIFT = 10;//株価10倍格納する場合
- private const int RECORD_LENGTH = 32;
- public static void ImportData(string[] fileName)
- {
- var code = -1;
- DataFarm farm = null;
- var dicCsv = new SortedDictionary<int, NewDailyData2>();//読み込みCSVファイル情報
- var dicFarm = new SortedDictionary<int, NewDailyData2>();//OmegaChartのdataフォルダ配下の情報
- var dicResult = new SortedDictionary<int, NewDailyData2>();//比較結果格納
- if (fileName.Length == 0) return;
- var path = fileName[0];
- if (IsTextFile(path))//複数ファイルNG
- {
- ReadCsv(path, ref dicCsv);
- DecisionCodeAndFarm(path, ref code, ref farm);
- if (farm.RawDataImage!=null)
- ReadFarm(farm, ref dicFarm);
- CompareCsvFarm(farm, dicCsv, dicFarm, ref dicResult);
- UpdateFarm(dicResult, ref dicFarm);
- WriteFarm(code, dicResult, dicFarm);
- }
- }
- private static void DecisionCodeAndFarm(string path, ref int code, ref DataFarm farm)
- {
- farm = Env.Frame.ChartCanvas.GetBrand().ReserveFarm();
- code = Path2IntCode(path);
- if (code < 0)//パス名が数字じゃなかったら、表示中の銘柄にインポートするものとする
- {
- code = farm.Brand.Code;
- }
- else//パス名が数字4文字含みだったら銘柄コードと決めつける
- {
- AbstractBrand br = Env.BrandCollection.FindBrand(code);
- if (br == null)//銘柄コードじゃなかったら戻す farmは最初から表示中のfarmを入れてある
- code = farm.Brand.Code;
- else
- farm = Env.BrandCollection.ReserveFarm(br);
- }
- }
- private static int Path2IntCode(string path)
- {
- var code = -1;
- var s = Path.GetFileName(path.Trim());
- if (s == string.Empty) return code;
- var sp = s.Split('.');
- if (sp[0].Length == 4)
- int.TryParse(sp[0], out code);
- return code;
- }
- private static void MakeBackupFile(int code)
- {
- var source = Util.GetDailyDataFileName(code);
- var dest = string.Format("{0}\\{1}.bak", Path.GetDirectoryName(source), code);
- File.Copy(source, dest, true);
- }
- private static void UpdateFarm(SortedDictionary<int, NewDailyData2> dicResult, ref SortedDictionary<int, NewDailyData2> dicFarm)
- {
- List<int> keyListResult = new List<int>(dicResult.Keys);
- foreach (var e in keyListResult)
- {
- if (dicFarm.ContainsKey(e))//キー(日付)が重複、かつ変更された日付の情報
- {
- //dicFarm[e] = dicResult[e];
- dicFarm[e].open = dicResult[e].open;
- dicFarm[e].high = dicResult[e].high;
- dicFarm[e].low = dicResult[e].low;
- dicFarm[e].close = dicResult[e].close;
- dicFarm[e].volume = dicResult[e].volume;
- }
- else//新規データ
- {
- dicFarm.Add(e, dicResult[e]);
- }
- }
- }
- private static void WriteFarm(int code, SortedDictionary<int, NewDailyData2> dicResult, SortedDictionary<int, NewDailyData2> dicFarm)
- {
- if (dicResult.Count > 0)
- {
- var message = string.Empty;
- message = string.Format("OmegaChartのデータを変更しますか?\n\n銘柄コード:{0:D4} 変更箇所数:{1}\n", code, dicResult.Count);
- List<int> keyListResult = new List<int>(dicResult.Keys);
- var cnt = 0;
- foreach (var key in keyListResult)
- {
- message += string.Format("{0:D8},{1},{2},{3},{4},{5}\n"
- , key
- , dicResult[key].open / SHIFT
- , dicResult[key].high / SHIFT
- , dicResult[key].low / SHIFT
- , dicResult[key].close / SHIFT
- , dicResult[key].volume);
- cnt++;
- if (cnt > 3)
- {
- message += "・・・以下略・・・";
- break;
- }
- }
- DialogResult result = MessageBox.Show(message, "質問", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2);
- if (result == DialogResult.OK)
- {
- MakeBackupFile(code);
- UpdateDataFarm(code, dicFarm);
- AbstractBrand br = Env.BrandCollection.FindBrand(code);
- CommandExec.ShowBrand(br);
- //CommandExec.RefreshChart();
- }
- }
- }
- private static void ReadFarm(DataFarm farm, ref SortedDictionary<int, NewDailyData2> dic)
- {
- for (var i = 0; i < farm.RawDataImage.Length / 32; i++)
- {
- var date = BitConverter.ToInt32(farm.RawDataImage, i * 32);
- NewDailyData2 ndd = new NewDailyData2();
- ndd.open = BitConverter.ToInt32(farm.RawDataImage, i * 32 + 4);
- ndd.high = BitConverter.ToInt32(farm.RawDataImage, i * 32 + 8);
- ndd.low = BitConverter.ToInt32(farm.RawDataImage, i * 32 + 12);
- ndd.close = BitConverter.ToInt32(farm.RawDataImage, i * 32 + 16);
- ndd.volume = BitConverter.ToInt32(farm.RawDataImage, i * 32 + 20);
- ndd.creditlong = BitConverter.ToInt32(farm.RawDataImage, i * 32 + 24);
- ndd.creditshort = BitConverter.ToInt32(farm.RawDataImage, i * 32 + 28);
- dic.Add(date, ndd);
- }
- }
- private static void CompareCsvFarm(DataFarm farm, SortedDictionary<int, NewDailyData2> dicCsv, SortedDictionary<int, NewDailyData2> dicFarm, ref SortedDictionary<int, NewDailyData2> dicResult)
- {
- List<int> keyList = new List<int>(dicCsv.Keys);
- foreach (var key in keyList)
- {
- if (dicCsv[key].volume == 0)
- {//個別銘柄で出来高ゼロの場合は特別作業が必要。OmegaChartは出来高がない日は前の日の値で埋められているため
- if (farm.Brand != null && farm.Brand.Market != MarketType.B && farm.Brand.Market != MarketType.Custom)
- {
- NewDailyData2 ndd = new NewDailyData2();
- ndd.open = 0;
- ndd.high = 0;
- ndd.low = 0;
- ndd.close = 0;
- ndd.volume = 0;
- dicCsv[key] = ndd;
- }
- }
- if (!dicFarm.ContainsKey(key))
- dicResult.Add(key, dicCsv[key]);
- else
- {
- if (dicFarm[key].open != dicCsv[key].open
- || dicFarm[key].high != dicCsv[key].high
- || dicFarm[key].low != dicCsv[key].low
- || dicFarm[key].close != dicCsv[key].close
- || dicFarm[key].volume != dicCsv[key].volume)
- dicResult.Add(key, dicCsv[key]);
- }
- }
- }
- private static void ReadCsv(string filename, ref SortedDictionary<int, NewDailyData2> dic)
- {
- System.Text.Encoding enc = System.Text.Encoding.GetEncoding("shift_jis");
- var str = System.IO.File.ReadAllText(filename, enc).Replace("\r", "");
- var lines = str.Split('\n');
- for (var i = 0; i < lines.Length; i++)
- {
- var sp = lines[i].Split(',');
- if (sp.Length != 6) continue;
- var dt = DateTime.MinValue;
- NewDailyData2 ndd = new NewDailyData2();
- double open = .0;
- double high = .0;
- double low = .0;
- double close = .0;
- if (DateTime.TryParse(sp[0], out dt)
- && double.TryParse(sp[1], out open)
- && double.TryParse(sp[2], out high)
- && double.TryParse(sp[3], out low)
- && double.TryParse(sp[4], out close)
- && int.TryParse(sp[5], out ndd.volume))
- {
- ndd.open = (int)(open * SHIFT);
- ndd.high = (int)(high * SHIFT);
- ndd.low = (int)(low * SHIFT);
- ndd.close = (int)(close * SHIFT);
- if (dt != DateTime.MinValue)
- dic.Add(int.Parse(dt.ToString("yyyyMMdd")), ndd);
- }
- }
- }
- private static void UpdateDataFarm(int code, SortedDictionary<int, NewDailyData2> prices)
- {
- var farm = (DailyDataFarm)Env.BrandCollection.FindBrand(code).CreateDailyFarm(prices.Count);
- var empty = farm.IsEmpty;
- var skip = true;
- foreach (var pair in prices)
- {
- if (empty && skip && pair.Value.volume == 0)
- continue;
- skip = false;
- farm.UpdateDataFarm(pair.Key, pair.Value);
- }
- farm.Save(Util.GetDailyDataFileName(code));
- }
- private static bool IsTextFile(string filePath)
- {
- var file = new System.IO.FileStream(filePath, FileMode.Open, FileAccess.Read);
- var byteData = new byte[1];
- while (file.Read(byteData, 0, byteData.Length) > 0)
- {
- if (byteData[0] == 0)
- return false;
- }
- return true;
- }
- }
- }