using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.ServiceModel; using System.Xml; using DevExpress.StockMarketTrader.StockDataServiceReference; namespace DevExpress.StockMarketTrader.Model.Offline { public class Company { public int ID { get; set; } public string CompanyName { get; set; } public Company() { } } public class OfflineStockData { public double CloseP { get; set; } public double HighP { get; set; } public double LowP { get; set; } public double OpenP { get; set; } public double Price { get; set; } public int CompanyID { get; set; } public int Volume { get; set; } public DateTime Date { get; set; } public OfflineStockData() { } } public class XmlStockDataProvider { const string companiesPath = "DevExpress.StockMarketTrader.Data.Companies.xml"; const string dataPath = "DevExpress.StockMarketTrader.Data.StockData.xml"; static List companies; static List stockData; static XmlStockDataProvider() { PopulateCompanies(); PopulateStockData(); } static void PopulateStockData() { Stream stream = GetResourceStream(dataPath); if (stream != null) { stockData = new List(); XmlDocument doc = new XmlDocument(); doc.Load(stream); var nodes = doc.LastChild.SelectNodes("//StockData"); foreach (XmlNode node in nodes) { var data = new OfflineStockData() { CompanyID = Int32.Parse(node.Attributes["Name"].Value), Date = DateTime.Parse(node.Attributes["Date"].Value, CultureInfo.InvariantCulture), Price = Double.Parse(node.Attributes["Price"].Value, CultureInfo.InvariantCulture), OpenP = Double.Parse(node.Attributes["Open"].Value, CultureInfo.InvariantCulture), CloseP = Double.Parse(node.Attributes["Close"].Value, CultureInfo.InvariantCulture), HighP = Double.Parse(node.Attributes["High"].Value, CultureInfo.InvariantCulture), LowP = Double.Parse(node.Attributes["Low"].Value, CultureInfo.InvariantCulture), Volume = int.Parse(node.Attributes["Volume"].Value, CultureInfo.InvariantCulture), }; stockData.Add(data); } } stream.Close(); } static void PopulateCompanies() { Stream stream = GetResourceStream(companiesPath); if (stream != null) { XmlDocument doc = new XmlDocument(); doc.Load(stream); var nodes = doc.LastChild.SelectNodes("//Company"); companies = new List(); foreach (XmlNode node in nodes) { companies.Add(new Company() { ID = Int32.Parse(node.Attributes["Id"].Value), CompanyName = node.Attributes["Name"].Value }); } stream.Close(); } } static Stream GetResourceStream(string path) { return Assembly.GetExecutingAssembly().GetManifestResourceStream(path); } public List Companies { get { return companies; } } public List StockData { get { return stockData; } } } public class StockDataOfflineService :/* ClientBase,*/ IStockDataService { static DateTime[] dates; readonly XmlStockDataProvider dataProvider; readonly Dictionary executions; readonly List sem = new List(); public StockDataOfflineService() { dataProvider = new XmlStockDataProvider(); executions = new Dictionary(); } #region IStockDataService Members string IStockDataService.Test() { return string.Empty; } void IStockDataService.Initialize() { throw new NotImplementedException(); } void StockDataServiceReference.IStockDataService.EndInitialize(IAsyncResult result) { throw new NotImplementedException(); } int[] IStockDataService.GetTopRatedCompanyIDs(DateTime date) { throw new NotImplementedException(); } int[] IStockDataService.EndGetTopRatedCompanyIDs(IAsyncResult result) { throw new NotImplementedException(); } double IStockDataService.GetHighestPrice(string companyName, DateTime start, DateTime end) { throw new NotImplementedException(); } double IStockDataService.EndGetHighestPrice(IAsyncResult result) { throw new NotImplementedException(); } double IStockDataService.GetLowestPrice(string companyName, DateTime start, DateTime end) { throw new NotImplementedException(); } double IStockDataService.EndGetLowestPrice(IAsyncResult result) { throw new NotImplementedException(); } string IStockDataService.EndTest(IAsyncResult result) { throw new NotImplementedException(); } StockData[] IStockDataService.GetAllPeriodData(string companyName) { throw new NotImplementedException(); } StockData[] IStockDataService.EndGetCompanyStockDataSL(IAsyncResult result) { throw new NotImplementedException(); } StockData[] IStockDataService.EndGetAllPeriodData(IAsyncResult result) { throw new NotImplementedException(); } StockData[] IStockDataService.GetCompanyStockDataSL(DateTime newDate, DateTime oldDate, string companyName) { throw new NotImplementedException(); } IAsyncResult IStockDataService.BeginInitialize(AsyncCallback callback, object asyncState) { throw new NotImplementedException(); } IAsyncResult IStockDataService.BeginTest(AsyncCallback callback, object asyncState) { throw new NotImplementedException(); } IAsyncResult IStockDataService.BeginGetAllPeriodData(string companyName, AsyncCallback callback, object asyncState) { throw new NotImplementedException(); } IAsyncResult IStockDataService.BeginGetCompanyStockDataSL(DateTime newDate, DateTime oldDate, string companyName, AsyncCallback callback, object asyncState) { throw new NotImplementedException(); } IAsyncResult IStockDataService.BeginGetHighestPrice(string companyName, DateTime start, DateTime end, AsyncCallback callback, object asyncState) { throw new NotImplementedException(); } IAsyncResult IStockDataService.BeginGetLowestPrice(string companyName, DateTime start, DateTime end, AsyncCallback callback, object asyncState) { throw new NotImplementedException(); } IAsyncResult IStockDataService.BeginGetTopRatedCompanyIDs(DateTime date, AsyncCallback callback, object asyncState) { throw new NotImplementedException(); } IAsyncResult IStockDataService.BeginGetTopRatedCompaniesDataSL(DateTime start, DateTime end, string selectedCompany, AsyncCallback callback, object asyncState) { throw new NotImplementedException(); } IAsyncResult IStockDataService.BeginGetCompanyData(DateTime newDate, DateTime oldDate, string companyName, AsyncCallback callback, object asyncState) { throw new NotImplementedException(); } CompanyData IStockDataService.GetCompanyData(DateTime newDate, DateTime oldDate, string companyName) { throw new NotImplementedException(); } CompanyData IStockDataService.EndGetCompanyData(IAsyncResult result) { throw new NotImplementedException(); } TopRatedCompanyData[] IStockDataService.GetTopRatedCompaniesDataSL(DateTime start, DateTime end, string selectedCompany) { throw new NotImplementedException(); } TopRatedCompanyData[] IStockDataService.EndGetTopRatedCompaniesDataSL(IAsyncResult result) { throw new NotImplementedException(); } #endregion void AddExecution(Delegate d, IAsyncResult result) { executions.Add(result, d); } void RemoveExecution(IAsyncResult result) { executions.Remove(result); } string GetCompanyNameByID(int id) { lock (sem) { return GetCompanies().Where(e => e.ID == id).Select(e => e.CompanyName).ToArray()[0]; } } double GetHighLowPriceBetweenDates(OfflineStockData[] data, DateTime start, DateTime end, string companyName, bool isMax) { int id = GetCompanyID(companyName); if (isMax) return (double)data.Where(e => e.Date >= start && e.Date <= end && e.CompanyID == id).Select(e => e.HighP).Max(); else return (double)data.Where(e => e.Date >= start && e.Date <= end && e.CompanyID == id).Select(e => e.LowP).Min(); } int GetCompanyID(string companyName) { lock (sem) { return GetCompanies().Where(e => e.CompanyName == companyName).Select(e => e.ID).ToList().FirstOrDefault(); } } int[] GetTopRatedCompanyIDs(DateTime date) { IOrderedEnumerable data = GetStockDataByDate2(date).OrderByDescending((e => e.Volume)); int[] ids = data.Select(e => e.CompanyID).ToArray(); int[] result = new int[ids.Length]; for (int i = 0; i < result.Length; i++) { result[i] = ids[i]; } return result; } Delegate GetExecution(IAsyncResult result) { return executions[result]; } StockData GetServiceStockData(OfflineStockData data) { return new StockData() { CompanyID = data.CompanyID, Date = data.Date, Price = Convert.ToDecimal(data.Price), OpenP = Convert.ToDecimal(data.OpenP), CloseP = Convert.ToDecimal(data.CloseP), HighP = Convert.ToDecimal(data.HighP), LowP = Convert.ToDecimal(data.LowP), Volumne = data.Volume }; } OfflineStockData[] GetMultipleCompanyStockData(List datesList, string companyName) { int id = GetCompanyID(companyName); return GetStockData().Where(e => e.CompanyID == id && datesList.Contains(e.Date)).Select(e => e).OrderBy(e => e.Date).ToArray(); } OfflineStockData[] GetStockDataByDate2(DateTime currentDate) { List data = GetStockData(); OfflineStockData[] result = data.Where(e => e.Date == currentDate).OrderBy(e => e.CompanyID).ToArray(); return result; } public string[] GetCompaniesName() { lock (sem) { return GetCompanies().Select(e => e.CompanyName).ToArray(); } } public string[] EndGetCompaniesName(IAsyncResult result) { var endResult = ((Func)GetExecution(result)).EndInvoke(result); RemoveExecution(result); return endResult; } public IAsyncResult BeginGetCompanyMultipleDataFromPeriod(int currentDate, int count, int periodSize, string companyName, AsyncCallback callback, object asyncState) { Func f = new Func(GetCompanyMultipleDataFromPeriod); var result = f.BeginInvoke(currentDate, count, periodSize, companyName, callback, asyncState); AddExecution(f, result); return result; } public IAsyncResult BeginGetStockDataFromPeriodByCompanyList(int currentDate, int count, int periodSize, string[] companies, AsyncCallback callback, object asyncState) { Func f = new Func(GetStockDataFromPeriodByCompanyList); var result = f.BeginInvoke(currentDate, count, periodSize, companies, callback, asyncState); AddExecution(f, result); return result; } public IAsyncResult BeginGetStockDataFromDateByCompanyList(DateTime date, string[] companies, AsyncCallback callback, object asyncState) { Func f = new Func(GetStockDataFromDateByCompanyList); var result = f.BeginInvoke(date, companies, callback, asyncState); AddExecution(f, result); return result; } public IAsyncResult BeginGetDates(AsyncCallback callback, object asyncState) { Func f = new Func(GetDates); var result = f.BeginInvoke(callback, asyncState); AddExecution(f, result); return result; } public IAsyncResult BeginGetStockDataByDate(DateTime currentDate, AsyncCallback callback, object asyncState) { Func f = new Func(GetStockDataByDate); var result = f.BeginInvoke(currentDate, callback, asyncState); AddExecution(f, result); return result; } public IAsyncResult BeginGetCompaniesName(AsyncCallback callback, object asyncState) { Func f = new Func(GetCompaniesName); var result = f.BeginInvoke(callback, asyncState); AddExecution(f, result); return result; } public IAsyncResult BeginGetCompanyStockData(DateTime date, string companyName, AsyncCallback callback, object asyncState) { Func f = new Func(GetCompanyStockData); var result = f.BeginInvoke(date, companyName, callback, asyncState); AddExecution(f, result); return result; } public IAsyncResult BeginGetCompaniesVolumeFromPeriod(DateTime start, DateTime end, AsyncCallback callback, object asyncState) { Func f = new Func(GetCompaniesVolumeFromPeriod); var result = f.BeginInvoke(start, end, callback, asyncState); AddExecution(f, result); return result; } public CompanyData[] GetCompanyMultipleDataFromPeriod(int currentDate, int count, int periodSize, string companyName) { lock (sem) { List datesList = new List(); int dateCount = currentDate; for (int i = 0; i < (count + 1) * periodSize; i++) { if (dateCount < dates.Length) { datesList.Add(dates[dateCount]); dateCount++; } } OfflineStockData[] data = GetMultipleCompanyStockData(datesList, companyName); List result = new List(); for (int i = 0; i < count; i++) { DateTime nextDate = datesList[(i + 1) * periodSize]; double closePrice = (double)data[(i + 1) * periodSize].CloseP; double highPrice = GetHighLowPriceBetweenDates(data, dates[currentDate], dates[currentDate + periodSize], companyName, true); double lowPrice = GetHighLowPriceBetweenDates(data, dates[currentDate], dates[currentDate + periodSize], companyName, false); currentDate += periodSize; result.Add(new CompanyData() { Data = GetServiceStockData(data[i * periodSize]), HighPrice = highPrice, LowPrice = lowPrice, ClosePrice = closePrice }); } return result.ToArray(); } } public CompanyData[] EndGetCompanyMultipleDataFromPeriod(IAsyncResult result) { var endResult = ((Func)GetExecution(result)).EndInvoke(result); RemoveExecution(result); return endResult; } public CompanyStockData[] GetStockDataFromPeriodByCompanyList(int currentDate, int count, int periodSize, string[] companies) { lock(sem) { List result = new List(); foreach (string company in companies) { var data = GetCompanyMultipleDataFromPeriod(currentDate, count, periodSize, company); if (data != null) result.Add(new CompanyStockData() { Data = data.Select(d => d.Data).ToArray(), CompanyName = company }); } return result.ToArray(); } } public CompanyStockData[] EndGetStockDataFromPeriodByCompanyList(IAsyncResult result) { var endResult = ((Func)GetExecution(result)).EndInvoke(result); RemoveExecution(result); return endResult; } public CompanyStockData[] GetStockDataFromDateByCompanyList(DateTime date, string[] companies) { lock(sem) { List result = new List(); foreach(string company in companies) { StockData[] data = ((IStockDataService)this).GetCompanyStockData(date, company); result.Add(new CompanyStockData() { Data = data, CompanyName = company }); } return result.ToArray(); } } public CompanyStockData[] EndGetStockDataFromDateByCompanyList(IAsyncResult result) { var endResult = ((Func)GetExecution(result)).EndInvoke(result); RemoveExecution(result); return endResult; } public List GetCompanies() { return dataProvider.Companies; } public List GetStockData() { return dataProvider.StockData; } public DateTime[] GetDates() { if (dates == null || dates.Length == 0) { lock (sem) { dates = GetStockData().Select(e => e.Date).Distinct().OrderBy(e => e.Date).ToArray(); } } return dates; } public DateTime[] EndGetDates(IAsyncResult result) { var endResult = ((Func)executions[result]).EndInvoke(result); RemoveExecution(result); return endResult; } public StockData[] GetStockDataByDate(DateTime currentDate) { lock (sem) { StockData[] result = GetStockData().Where(e => e.Date == currentDate).OrderBy(e => e.CompanyID).Select(e => GetServiceStockData(e)).ToArray(); return result; } } public StockData[] EndGetStockDataByDate(IAsyncResult result) { var endResult = ((Func)GetExecution(result)).EndInvoke(result); RemoveExecution(result); return endResult; } public StockData[] GetCompanyStockData(DateTime date, string companyName) { lock (sem) { int id = GetCompanyID(companyName); return GetStockData().Where(e => e.CompanyID == id && e.Date == date).Select(e => GetServiceStockData(e)).ToArray(); } } public StockData[] EndGetCompanyStockData(IAsyncResult result) { var endresult = ((Func)GetExecution(result)).EndInvoke(result); RemoveExecution(result); return endresult; } public CompaniesVolumeData[] GetCompaniesVolumeFromPeriod(DateTime start, DateTime end) { lock (sem) { int[] topIds = GetTopRatedCompanyIDs(start); CompaniesVolumeData[] result = new CompaniesVolumeData[topIds.Length]; for (int i = 0; i < topIds.Length; i++) { int volume = GetStockData().Where(e => e.Date >= start && e.CompanyID == topIds[i]).Select(e => e.Volume).ToArray()[0]; CompaniesVolumeData data = new CompaniesVolumeData() { CompanyName = GetCompanyNameByID(topIds[i]), Volume = (int)volume }; result[i] = data; } return result; } } public CompaniesVolumeData[] EndGetCompaniesVolumeFromPeriod(IAsyncResult result) { var endResult = ((Func)GetExecution(result)).EndInvoke(result); RemoveExecution(result); return endResult; } } }