namespace IndexFormula.Finance.DataProvider { using System; using System.Collections; using System.Data; using System.IO; using System.Runtime.InteropServices; using System.Text; using System.Threading; public class MSDataManager : DataManagerBase { private int Fields = 7; private string FilePath; private Master[] Masters; private MetaStockTimeFrame TimeFrame = MetaStockTimeFrame.Daily; private XMaster[] XMasters; public MSDataManager(string FilePath) { FilePath = Path.GetDirectoryName(FilePath); if (!FilePath.EndsWith(@"\")) { FilePath = FilePath + @"\"; } this.FilePath = FilePath; if (File.Exists(FilePath + "XMASTER")) { this.LoadXMaster(); } if (!File.Exists(FilePath + "MASTER")) { throw new Exception("MetaStock Path Not Found!" + FilePath + "MASTER"); } this.LoadMaster(); } public override int DeleteSymbols(string Exchange, string[] Symbols, bool Remain, bool DeleteRealtime, bool DeleteHistorical) { ArrayList list = new ArrayList(); int num = 0; if (this.Masters != null) { list.AddRange(this.Masters); int index = 0; while (index < list.Count) { if (Array.IndexOf(Symbols, (list[index] as Master).symbol) >= 0) { list.RemoveAt(index); num++; } else { index++; } } if (num > 0) { this.Masters = (Master[]) list.ToArray(typeof(Master)); this.SaveMaster(); } } if (this.XMasters != null) { list.Clear(); num = 0; list.AddRange(this.XMasters); int num3 = 0; while (num3 < list.Count) { if (Array.IndexOf(Symbols, (list[num3] as XMaster).StockSymbol) >= 0) { list.RemoveAt(num3); num++; } else { num3++; } } if (num > 0) { this.XMasters = (XMaster[]) list.ToArray(typeof(XMaster)); this.SaveXMaster(); } } return num; } private void fieee2msbin(float[] ff) { uint[] dst = new uint[ff.Length]; Buffer.BlockCopy(ff, 0, dst, 0, ff.Length * 4); for (int i = 0; i < ff.Length; i++) { if (dst[i] != 0) { uint num = dst[i] >> 0x10; uint num2 = ((num << 1) & 0xff00) + 0x200; if ((num2 & 0x8000) == ((num << 1) & 0x8000)) { num = (num & 0x7f) | ((num >> 8) & 0x80); num |= num2; dst[i] = (dst[i] & 0xffff) | (num << 0x10); } } } Buffer.BlockCopy(dst, 0, ff, 0, ff.Length * 4); } public Master FindByNumber(string Number) { foreach (Master master in this.Masters) { if (("F" + master.file_num) == Number) { return master; } } return null; } public Master FindBySymbol(string Symbol, out XMaster xm) { xm = null; if (this.Masters != null) { foreach (Master master in this.Masters) { if (master.symbol == Symbol) { return master; } } } if (this.XMasters != null) { foreach (XMaster master2 in this.XMasters) { if (master2.StockSymbol == Symbol) { xm = master2; return null; } } } return null; } private void fmsbin2ieee(float[] ff) { uint[] dst = new uint[ff.Length]; Buffer.BlockCopy(ff, 0, dst, 0, ff.Length * 4); for (int i = 0; i < ff.Length; i++) { if (dst[i] != 0) { uint num = dst[i] >> 0x10; uint num2 = (num & 0xff00) - 0x200; num = (num & 0x7f) | ((num << 8) & 0x8000); num |= num2 >> 1; dst[i] = (dst[i] & 0xffff) | (num << 0x10); } } Buffer.BlockCopy(dst, 0, ff, 0, ff.Length * 4); } public override IDataProvider GetData(string Code, int Count) { CommonDataProvider cdp = new CommonDataProvider(this); string path = this.LookupDataFile(Code, cdp, ref this.Fields, ref this.TimeFrame); if ((path != "") && File.Exists(path)) { using (FileStream stream = this.ReadData(path)) { byte[] buffer = new byte[this.Fields * 4]; byte[] buffer2 = new byte[stream.Length - buffer.Length]; stream.Read(buffer, 0, buffer.Length); stream.Read(buffer2, 0, buffer2.Length); float[] dst = new float[buffer2.Length / 4]; Buffer.BlockCopy(buffer2, 0, dst, 0, buffer2.Length); this.fmsbin2ieee(dst); int num = dst.Length / this.Fields; double[] numArray2 = new double[num]; double[] numArray3 = new double[num]; double[] numArray4 = new double[num]; double[] numArray5 = new double[num]; double[] numArray6 = new double[num]; double[] numArray7 = new double[num]; double[] numArray8 = new double[num]; if (this.Fields == 5) { numArray3 = numArray6; numArray8 = numArray6; } for (int i = 0; i < num; i++) { int num3 = (int) dst[i * this.Fields]; DateTime time = new DateTime((num3 / 0x2710) + 0x76c, (num3 / 100) % 100, num3 % 100); int num4 = 0; if ((this.Fields == 8) || (this.TimeFrame == MetaStockTimeFrame.Intraday)) { int num5 = (int) dst[(i * this.Fields) + 1]; time += new TimeSpan(num5 / 0x2710, (num5 / 100) % 100, num5 % 100); num4 = 1; } numArray2[i] = time.ToOADate(); if (this.Fields >= 6) { numArray3[i] = dst[((i * this.Fields) + 1) + num4]; numArray4[i] = dst[((i * this.Fields) + 2) + num4]; numArray5[i] = dst[((i * this.Fields) + 3) + num4]; numArray6[i] = dst[((i * this.Fields) + 4) + num4]; numArray7[i] = dst[((i * this.Fields) + 5) + num4]; numArray8[i] = numArray6[i]; } else { numArray4[i] = dst[(i * this.Fields) + 1]; numArray5[i] = dst[(i * this.Fields) + 2]; numArray6[i] = dst[(i * this.Fields) + 3]; numArray7[i] = dst[(i * this.Fields) + 4]; } } cdp.LoadBinary(new double[][] { numArray3, numArray4, numArray5, numArray6, numArray7, numArray2, numArray8 }); return cdp; } } cdp.LoadByteBinary(new byte[0]); return cdp; } private byte[] GetEmptyByteArray(int Count, byte Fill) { byte[] buffer = new byte[Count]; for (int i = 0; i < buffer.Length; i++) { buffer[i] = Fill; } return buffer; } public override DataTable GetStockList(string Exchange, string ConditionId, string Key, string Sort, int StartRecords, int MaxRecords) { return base.RecordRange(this.GetTable(), StartRecords, MaxRecords); } public string GetSymbol(string Number) { Master master = this.FindByNumber(Number); if (master == null) { return ""; } return master.symbol.Trim(); } public override DataTable GetSymbolList(string Exchange, string ConditionId, string Key, string Sort, int StartRecords, int MaxRecords) { return base.RecordRange(this.GetTable(), StartRecords, MaxRecords); } public DataTable GetTable() { DataTable table = new DataTable(); table.Columns.Add("Symbol"); table.Columns.Add("Name"); if (this.Masters != null) { foreach (Master master in this.Masters) { table.Rows.Add(new object[] { master.symbol, master.issue_name }); } } if (this.XMasters != null) { foreach (XMaster master2 in this.XMasters) { table.Rows.Add(new object[] { master2.StockSymbol, master2.StockName }); } } return table; } private void LoadMaster() { using (FileStream stream = this.ReadData(this.FilePath + "MASTER")) { this.Masters = new Master[(stream.Length / 0x35L) - 1L]; using (BinaryReader reader = new BinaryReader(stream)) { reader.ReadBytes(0x35); int index = 0; do { this.Masters[index] = new Master(); this.Masters[index].file_num = reader.ReadByte(); this.Masters[index].file_type = reader.ReadBytes(2); this.Masters[index].rec_len = reader.ReadByte(); this.Masters[index].num_fields = reader.ReadByte(); this.Masters[index].reserved1 = reader.ReadBytes(2); this.Masters[index].issue_name = Encoding.ASCII.GetString(reader.ReadBytes(0x10)).Trim(); this.Masters[index].reserved2 = reader.ReadByte(); this.Masters[index].CT_v2_8_flag = reader.ReadByte(); this.Masters[index].first_date = reader.ReadSingle(); this.Masters[index].last_date = reader.ReadSingle(); this.Masters[index].time_frame = (MetaStockTimeFrame) reader.ReadByte(); this.Masters[index].ida_time = reader.ReadInt16(); this.Masters[index].symbol = Encoding.ASCII.GetString(reader.ReadBytes(14)).Trim(); this.Masters[index].reserved3 = reader.ReadByte(); this.Masters[index].flag = reader.ReadByte(); this.Masters[index].reserved4 = reader.ReadByte(); index++; } while (index < this.Masters.Length); } } } private void LoadXMaster() { using (FileStream stream = this.ReadData(this.FilePath + "XMASTER")) { this.XMasters = new XMaster[(stream.Length / 150L) - 1L]; using (BinaryReader reader = new BinaryReader(stream)) { reader.ReadBytes(150); int index = 0; do { this.XMasters[index] = new XMaster(); this.XMasters[index].Unknown1 = reader.ReadByte(); this.XMasters[index].StockSymbol = this.TrimToZero(Encoding.ASCII.GetString(reader.ReadBytes(15))); this.XMasters[index].StockName = this.TrimToZero(Encoding.ASCII.GetString(reader.ReadBytes(0x2e))); this.XMasters[index].TimeFrame = (MetaStockTimeFrame) reader.ReadByte(); this.XMasters[index].Unknown2 = reader.ReadBytes(2); this.XMasters[index].Fn = reader.ReadInt16(); this.XMasters[index].Unknown3 = reader.ReadBytes(13); this.XMasters[index].EndDate = reader.ReadInt32(); this.XMasters[index].Unknown4 = reader.ReadBytes(20); this.XMasters[index].StartDate = reader.ReadInt32(); this.XMasters[index].StartDate2 = reader.ReadInt32(); this.XMasters[index].Unknown5 = reader.ReadBytes(4); this.XMasters[index].EndDate2 = reader.ReadInt32(); this.XMasters[index].Unknown6 = reader.ReadBytes(30); index++; } while (index < this.XMasters.Length); } } } public string LookupDataFile(string Code, CommonDataProvider cdp) { return this.LookupDataFile(Code, cdp, ref this.Fields, ref this.TimeFrame); } public string LookupDataFile(string Code, CommonDataProvider cdp, ref int Fields, ref MetaStockTimeFrame TimeFrame) { if (cdp != null) { cdp.SetStringData("Code", Code); } foreach (Master master in this.Masters) { if (string.Compare(master.symbol, Code, true) == 0) { if (cdp != null) { cdp.SetStringData("Name", master.issue_name); } Fields = master.num_fields; TimeFrame = master.time_frame; return string.Concat(new object[] { this.FilePath, "F", master.file_num, ".DAT" }); } } if (this.XMasters != null) { foreach (XMaster master2 in this.XMasters) { if (string.Compare(master2.StockSymbol, Code, true) == 0) { if (cdp != null) { cdp.SetStringData("Name", master2.StockName); } TimeFrame = master2.TimeFrame; return string.Concat(new object[] { this.FilePath, "F", master2.Fn, ".MWD" }); } } } return ""; } private FileStream ReadData(string Filename) { for (int i = 5; i >= 0; i--) { try { return new FileStream(Filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); } catch { if (i == 0) { throw; } Thread.Sleep(100); } } return null; } public override void SaveData(string Symbol, IDataProvider idp, Stream OutStream, DateTime Start, DateTime End, bool Intraday) { CommonDataProvider cdp = (CommonDataProvider) idp; if ((Symbol != null) && (Symbol != "")) { XMaster master; int count = cdp.Count; Master master2 = this.FindBySymbol(Symbol, out master); bool flag = false; bool flag2 = false; this.Fields = (byte) (7 + (Intraday ? 1 : 0)); if ((master2 == null) && (master == null)) { int num2 = this.MaxNum + 1; if (num2 > 0xff) { master = new XMaster(); master.Fn = (short) num2; ArrayList list = new ArrayList(this.XMasters); master.StockSymbol = Symbol; master.StockName = cdp.GetStringData("Name"); if (master.StockName == null) { master.StockName = Symbol; } list.Add(master); this.XMasters = (XMaster[]) list.ToArray(typeof(XMaster)); flag2 = true; } else { master2 = new Master(); master2.file_num = (byte) num2; ArrayList list2 = new ArrayList(this.Masters); master2.symbol = Symbol; master2.num_fields = (byte) this.Fields; master2.issue_name = cdp.GetStringData("Name"); if (master2.issue_name == null) { master2.issue_name = Symbol; } list2.Add(master2); this.Masters = (Master[]) list2.ToArray(typeof(Master)); flag = true; } } double[] numArray = cdp["DATE"]; double[] numArray2 = cdp["OPEN"]; double[] numArray3 = cdp["HIGH"]; double[] numArray4 = cdp["LOW"]; double[] numArray5 = cdp["CLOSE"]; double[] numArray6 = cdp["VOLUME"]; double[] numArray7 = cdp["ADJCLOSE"]; float[] ff = new float[count * this.Fields]; for (int i = 0; i < count; i++) { int num4 = 0; DateTime time = DateTime.FromOADate(numArray[i]); ff[(i * this.Fields) + num4] = (((time.Year - 0x76c) * 0x2710) + (time.Month * 100)) + time.Day; if (this.Fields == 8) { num4 = 1; ff[(i * this.Fields) + num4] = ((time.Hour * 0x2710) + (time.Minute * 100)) + time.Second; } ff[((i * this.Fields) + 1) + num4] = (float) numArray2[i]; ff[((i * this.Fields) + 2) + num4] = (float) numArray3[i]; ff[((i * this.Fields) + 3) + num4] = (float) numArray4[i]; ff[((i * this.Fields) + 4) + num4] = (float) numArray5[i]; ff[((i * this.Fields) + 5) + num4] = (float) numArray6[i]; ff[((i * this.Fields) + 6) + num4] = (float) numArray5[i]; } this.fieee2msbin(ff); byte[] dst = new byte[ff.Length * 4]; Buffer.BlockCopy(ff, 0, dst, 0, dst.Length); using (FileStream stream = File.Create(this.LookupDataFile(Symbol, cdp))) { stream.Write(dst, 0, dst.Length); } if (flag) { this.SaveMaster(); } if (flag2) { this.SaveXMaster(); } } } private void SaveMaster() { using (FileStream stream = File.Create(this.FilePath + "MASTER")) { using (BinaryWriter writer = new BinaryWriter(stream)) { foreach (Master master in this.Masters) { writer.Write(master.file_num); writer.Write(master.file_type); writer.Write(master.rec_len); writer.Write((byte) this.Fields); writer.Write(master.reserved1); if ((master.issue_name == null) || (master.issue_name == "")) { master.issue_name = master.symbol; } writer.Write(this.StringToBytes(master.issue_name, 0x10, 0x20)); writer.Write(master.reserved2); writer.Write(master.CT_v2_8_flag); writer.Write(master.first_date); writer.Write(master.last_date); writer.Write((byte) master.time_frame); writer.Write(master.ida_time); writer.Write(this.StringToBytes(master.symbol, 14, 0x20)); writer.Write(master.reserved3); writer.Write(master.flag); writer.Write(master.reserved4); } } } } private void SaveXMaster() { using (FileStream stream = File.Create(this.FilePath + "XMaster")) { using (BinaryWriter writer = new BinaryWriter(stream)) { if (this.XMasters != null) { foreach (XMaster master in this.XMasters) { writer.Write(master.Unknown1); writer.Write(this.StringToBytes(master.StockSymbol, 15, 0)); writer.Write(this.StringToBytes(master.StockName, 0x2e, 0)); writer.Write((byte) master.TimeFrame); writer.Write(master.Unknown2); writer.Write(master.Fn); writer.Write(master.Unknown3); writer.Write(master.EndDate); writer.Write(master.Unknown4); writer.Write(master.StartDate); writer.Write(master.StartDate2); writer.Write(master.Unknown5); writer.Write(master.EndDate2); writer.Write(master.Unknown6); } } } } } private byte[] StringToBytes(string s, int Count, byte Fill) { byte[] emptyByteArray = this.GetEmptyByteArray(Count, Fill); Encoding.ASCII.GetBytes(s, 0, s.Length, emptyByteArray, 0); return emptyByteArray; } public override int SymbolCount(string Exchange, string ConditionId, string Key) { return this.GetTable().Rows.Count; } private string TrimToZero(string s) { for (int i = 0; i < s.Length; i++) { if (s[i] == '\0') { return s.Substring(0, i); } } return s; } public override DataTable Exchanges { get { DataTable table = new DataTable(); table.Columns.Add("Value"); table.Columns.Add("Text"); table.Rows.Add(new object[] { "", "ALL" }); return table; } } private int MaxNum { get { int fn = 1; if (this.Masters != null) { foreach (Master master in this.Masters) { if (fn < master.file_num) { fn = master.file_num; } } } if (this.XMasters != null) { foreach (XMaster master2 in this.XMasters) { if (fn < master2.Fn) { fn = master2.Fn; } } } return fn; } } } }