Files
netcore-winforms-demos/StockMarketTraderApp/Model/StockDataOfflineProvider.cs
2018-12-21 10:31:41 +03:00

418 lines
21 KiB
C#

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<Company> companies;
static List<OfflineStockData> stockData;
static XmlStockDataProvider() {
PopulateCompanies();
PopulateStockData();
}
static void PopulateStockData() {
Stream stream = GetResourceStream(dataPath);
if (stream != null) {
stockData = new List<OfflineStockData>();
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<Company>();
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<Company> Companies { get { return companies; } }
public List<OfflineStockData> StockData { get { return stockData; } }
}
public class StockDataOfflineService :/* ClientBase<IStockDataService>,*/ IStockDataService {
static DateTime[] dates;
readonly XmlStockDataProvider dataProvider;
readonly Dictionary<IAsyncResult, Delegate> executions;
readonly List<string> sem = new List<string>();
public StockDataOfflineService() {
dataProvider = new XmlStockDataProvider();
executions = new Dictionary<IAsyncResult, Delegate>();
}
#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<OfflineStockData> 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<DateTime> 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<OfflineStockData> 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<string[]>)GetExecution(result)).EndInvoke(result);
RemoveExecution(result);
return endResult;
}
public IAsyncResult BeginGetCompanyMultipleDataFromPeriod(int currentDate, int count, int periodSize, string companyName, AsyncCallback callback, object asyncState) {
Func<int, int, int, string, CompanyData[]> f = new Func<int, int, int, string, CompanyData[]>(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<int, int, int, string[], CompanyStockData[]> f = new Func<int, int, int, string[], CompanyStockData[]>(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<DateTime, string[], StockDataServiceReference.CompanyStockData[]> f = new Func<DateTime, string[], StockDataServiceReference.CompanyStockData[]>(GetStockDataFromDateByCompanyList);
var result = f.BeginInvoke(date, companies, callback, asyncState);
AddExecution(f, result);
return result;
}
public IAsyncResult BeginGetDates(AsyncCallback callback, object asyncState) {
Func<DateTime[]> f = new Func<DateTime[]>(GetDates);
var result = f.BeginInvoke(callback, asyncState);
AddExecution(f, result);
return result;
}
public IAsyncResult BeginGetStockDataByDate(DateTime currentDate, AsyncCallback callback, object asyncState) {
Func<DateTime, StockData[]> f = new Func<DateTime, StockData[]>(GetStockDataByDate);
var result = f.BeginInvoke(currentDate, callback, asyncState);
AddExecution(f, result);
return result;
}
public IAsyncResult BeginGetCompaniesName(AsyncCallback callback, object asyncState) {
Func<string[]> f = new Func<string[]>(GetCompaniesName);
var result = f.BeginInvoke(callback, asyncState);
AddExecution(f, result);
return result;
}
public IAsyncResult BeginGetCompanyStockData(DateTime date, string companyName, AsyncCallback callback, object asyncState) {
Func<DateTime, string, StockData[]> f = new Func<DateTime, string, StockData[]>(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<DateTime, DateTime, CompaniesVolumeData[]> f = new Func<DateTime, DateTime, CompaniesVolumeData[]>(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<DateTime> datesList = new List<DateTime>();
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<CompanyData> result = new List<CompanyData>();
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<int, int, int, string, CompanyData[]>)GetExecution(result)).EndInvoke(result);
RemoveExecution(result);
return endResult;
}
public CompanyStockData[] GetStockDataFromPeriodByCompanyList(int currentDate, int count, int periodSize, string[] companies) {
lock(sem) {
List<CompanyStockData> result = new List<CompanyStockData>();
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<int, int, int, string[], CompanyStockData[]>)GetExecution(result)).EndInvoke(result);
RemoveExecution(result);
return endResult;
}
public CompanyStockData[] GetStockDataFromDateByCompanyList(DateTime date, string[] companies) {
lock(sem) {
List<CompanyStockData> result = new List<CompanyStockData>();
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<DateTime, string[], StockDataServiceReference.CompanyStockData[]>)GetExecution(result)).EndInvoke(result);
RemoveExecution(result);
return endResult;
}
public List<Company> GetCompanies() {
return dataProvider.Companies;
}
public List<OfflineStockData> 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<DateTime[]>)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<DateTime, StockData[]>)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<DateTime, string, StockData[]>)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<DateTime, DateTime, CompaniesVolumeData[]>)GetExecution(result)).EndInvoke(result);
RemoveExecution(result);
return endResult;
}
}
}