mirror of
https://github.com/DevExpress/netcore-winforms-demos.git
synced 2026-01-09 18:24:06 +00:00
Add Outlook Inspired and Stock Market demos
This commit is contained in:
65
StockMarketTraderApp/Model/BusinessObjects.cs
Normal file
65
StockMarketTraderApp/Model/BusinessObjects.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using DevExpress.StockMarketTrader.StockDataServiceReference;
|
||||
|
||||
namespace DevExpress.StockMarketTrader.Model.BusinessObjects {
|
||||
public class TradingData {
|
||||
public DateTime Date { get; set; }
|
||||
public double Price { get; set; }
|
||||
public double Open { get; set; }
|
||||
public double Close { get; set; }
|
||||
public double High { get; set; }
|
||||
public double Low { get; set; }
|
||||
public double Volume { get; set; }
|
||||
|
||||
public TradingData() {
|
||||
}
|
||||
public TradingData(TradingData data) {
|
||||
Assign(data);
|
||||
}
|
||||
public void Assign(TradingData data) {
|
||||
Date = data.Date;
|
||||
Price = data.Price;
|
||||
Open = data.Open;
|
||||
Close = data.Close;
|
||||
High = data.High;
|
||||
Low = data.Low;
|
||||
Volume = data.Volume;
|
||||
}
|
||||
}
|
||||
|
||||
public class CompanyTradingData : TradingData {
|
||||
public string CompanyName { get; set; }
|
||||
|
||||
public CompanyTradingData(TradingData data, string companyName) : base(data) {
|
||||
CompanyName = companyName;
|
||||
}
|
||||
public CompanyTradingData(StockData data, string companyName) {
|
||||
Date = data.Date;
|
||||
Close = (double)data.CloseP;
|
||||
Open = (double)data.OpenP;
|
||||
Price = (double)data.Price;
|
||||
High = (double)data.HighP;
|
||||
Low = (double)data.LowP;
|
||||
Volume = data.Volumne;
|
||||
CompanyName = companyName;
|
||||
}
|
||||
}
|
||||
|
||||
public class TransactionData {
|
||||
string transactionType;
|
||||
int volume;
|
||||
double price;
|
||||
|
||||
public int Ask { get { return transactionType == "Ask" ? volume : 0; } }
|
||||
public int Bid { get { return transactionType == "Bid" ? volume : 0; } }
|
||||
public int Volume { get { return volume; } set { volume = value; } }
|
||||
public double Price { get { return price; } set { price = value; } }
|
||||
public string TransactionType { get { return transactionType; } }
|
||||
|
||||
public TransactionData(string transactionType, int volume, double price) {
|
||||
this.volume = volume;
|
||||
this.price = price;
|
||||
this.transactionType = transactionType;
|
||||
}
|
||||
}
|
||||
}
|
||||
121
StockMarketTraderApp/Model/Executor.cs
Normal file
121
StockMarketTraderApp/Model/Executor.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DevExpress.StockMarketTrader.Model {
|
||||
public enum ActionPriority {
|
||||
Normal,
|
||||
High,
|
||||
Blocked
|
||||
}
|
||||
|
||||
public enum ExecutorStatus {
|
||||
Enabled,
|
||||
Disabled,
|
||||
Offline
|
||||
}
|
||||
|
||||
public class UserStateParams {
|
||||
public Delegate Callback { get; private set; }
|
||||
public int ActionID { get; set; }
|
||||
|
||||
public UserStateParams(Delegate callback, int actionID) {
|
||||
if(callback != null)
|
||||
Callback = callback;
|
||||
ActionID = actionID;
|
||||
}
|
||||
}
|
||||
|
||||
public class ExecutorAction {
|
||||
readonly Delegate method;
|
||||
readonly ActionPriority priority;
|
||||
readonly object[] args;
|
||||
|
||||
public object[] Args { get { return args; } }
|
||||
public Delegate Method { get { return method; } }
|
||||
public ActionPriority Priority { get { return priority; } }
|
||||
|
||||
public ExecutorAction(Delegate method, ActionPriority priority, object[] args) {
|
||||
this.method = method;
|
||||
this.priority = priority;
|
||||
this.args = args;
|
||||
}
|
||||
}
|
||||
|
||||
public class Executor {
|
||||
readonly Stack<ExecutorAction> actions;
|
||||
readonly NetworkMonitor networkMonitor;
|
||||
ExecutorAction currentAction;
|
||||
ExecutorStatus status = ExecutorStatus.Disabled;
|
||||
int userID = 0, executingActions = 0;
|
||||
|
||||
public event EventHandler ExecuteFailed;
|
||||
|
||||
public int UserID { get { return userID; } }
|
||||
public int ExecutingActions { get { return executingActions; } }
|
||||
public ExecutorStatus Status {
|
||||
get { return status; }
|
||||
set {
|
||||
status = value;
|
||||
if (value == ExecutorStatus.Enabled)
|
||||
TryExecute(false);
|
||||
if (value == ExecutorStatus.Disabled && currentAction != null)
|
||||
actions.Push(currentAction);
|
||||
}
|
||||
}
|
||||
|
||||
public Executor(NetworkMonitor networkMonitor) {
|
||||
this.networkMonitor = networkMonitor;
|
||||
actions = new Stack<ExecutorAction>();
|
||||
}
|
||||
bool CanExecuteByNetwork() {
|
||||
bool isAvaliable = networkMonitor.IsInternetAvaliable;
|
||||
return isAvaliable || (!isAvaliable && status == ExecutorStatus.Offline);
|
||||
}
|
||||
void RaiseExecuteFailed() {
|
||||
ExecuteFailed(this, EventArgs.Empty);
|
||||
}
|
||||
void TryExecute(bool isForceExecute) {
|
||||
if (CanExecuteByNetwork() && actions.Count != 0 && (status != ExecutorStatus.Disabled && (actions.Peek().Priority != ActionPriority.Blocked || isForceExecute))) {
|
||||
currentAction = actions.Pop();
|
||||
BeginExecute(currentAction);
|
||||
}
|
||||
}
|
||||
void BeginExecute(ExecutorAction action) {
|
||||
try {
|
||||
executingActions++;
|
||||
action.Method.DynamicInvoke(action.Args);
|
||||
}
|
||||
catch {
|
||||
RaiseExecuteFailed();
|
||||
}
|
||||
}
|
||||
void Completed(object sender, EventArgs e) {
|
||||
ExecuteCompleted();
|
||||
}
|
||||
public void AddAction(ExecutorAction action) {
|
||||
actions.Push(action);
|
||||
TryExecute(false);
|
||||
}
|
||||
public void ExecuteCompleted() {
|
||||
TryExecute(false);
|
||||
}
|
||||
public void ChangeUserID() {
|
||||
actions.Clear();
|
||||
userID++;
|
||||
}
|
||||
public void ForceExecute() {
|
||||
TryExecute(true);
|
||||
}
|
||||
public void EndExecute(IAsyncResult result) {
|
||||
try {
|
||||
executingActions--;
|
||||
UserStateParams state = result.AsyncState as UserStateParams;
|
||||
if (state.ActionID == userID && state.Callback != null && status != ExecutorStatus.Disabled && CanExecuteByNetwork())
|
||||
state.Callback.DynamicInvoke(new object[] { result });
|
||||
}
|
||||
catch {
|
||||
RaiseExecuteFailed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
46
StockMarketTraderApp/Model/NetWorkMonitor.cs
Normal file
46
StockMarketTraderApp/Model/NetWorkMonitor.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace DevExpress.StockMarketTrader.Model {
|
||||
public class NetworkMonitor {
|
||||
const string serverName = "google.com";
|
||||
|
||||
readonly Timer timer;
|
||||
readonly Ping ping;
|
||||
bool isInit = false;
|
||||
|
||||
public event EventHandler<EventArgs> InternetAvaliableChanged;
|
||||
|
||||
public bool IsInternetAvaliable { get; private set; }
|
||||
|
||||
public NetworkMonitor() {
|
||||
ping = new Ping();
|
||||
ping.PingCompleted += PingCompleted;
|
||||
timer = new Timer() { Interval = 1 };
|
||||
timer.Tick += OnTimerTick;
|
||||
timer.Start();
|
||||
}
|
||||
void OnTimerTick(object sender, EventArgs e) {
|
||||
timer.Stop();
|
||||
ping.SendAsync(serverName, null);
|
||||
}
|
||||
void PingCompleted(object sender, PingCompletedEventArgs e) {
|
||||
bool isAvaliable = e.Reply == null || e.Reply.Status != IPStatus.Success ? false : true;
|
||||
if (isAvaliable != IsInternetAvaliable) {
|
||||
isInit = true;
|
||||
IsInternetAvaliable = isAvaliable;
|
||||
RaiseInternetAvaliableChanged();
|
||||
}
|
||||
else if (!isInit) {
|
||||
isInit = true;
|
||||
RaiseInternetAvaliableChanged();
|
||||
}
|
||||
//timer.Start();
|
||||
}
|
||||
void RaiseInternetAvaliableChanged() {
|
||||
if (InternetAvaliableChanged != null)
|
||||
InternetAvaliableChanged(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
209
StockMarketTraderApp/Model/RealTimeDataModel.cs
Normal file
209
StockMarketTraderApp/Model/RealTimeDataModel.cs
Normal file
@@ -0,0 +1,209 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using DevExpress.StockMarketTrader.Model.BusinessObjects;
|
||||
using DevExpress.StockMarketTrader.Model.Offline;
|
||||
using DevExpress.StockMarketTrader.StockDataServiceReference;
|
||||
|
||||
namespace DevExpress.StockMarketTrader.Model {
|
||||
public class PriceAscedingComparer : IComparer<TransactionData> {
|
||||
public int Compare(TransactionData x, TransactionData y) {
|
||||
if (x == null || y == null)
|
||||
return 0;
|
||||
if (x.Price == y.Price) {
|
||||
if (y.Bid == 0 && x.Ask == 0)
|
||||
return -1;
|
||||
else return 1;
|
||||
}
|
||||
if (x.Price < y.Price)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public class RealTimeDataEventArgs : EventArgs {
|
||||
public bool CanNewUpdate { get; set; }
|
||||
public string Key { get; set; }
|
||||
public string ExceptionMessage { get; set; }
|
||||
public object Data { get; set; }
|
||||
|
||||
public RealTimeDataEventArgs(object data, string key, bool canNewUpdate) {
|
||||
Data = data;
|
||||
Key = key;
|
||||
CanNewUpdate = canNewUpdate;
|
||||
}
|
||||
public RealTimeDataEventArgs(string message) {
|
||||
ExceptionMessage = message;
|
||||
}
|
||||
}
|
||||
|
||||
public class RealTimeDataModel {
|
||||
const string RemoteServerUnavailableMessage = "The remote server is not responding. Check your internet connection.";
|
||||
|
||||
readonly Executor executor;
|
||||
readonly NetworkMonitor networkMonitor;
|
||||
readonly Random rand;
|
||||
readonly List<TransactionData> transactions;
|
||||
readonly IComparer<TransactionData> comparer;
|
||||
bool isInitialized = false;
|
||||
StockDataOfflineService offlineService;
|
||||
|
||||
public event EventHandler<RealTimeDataEventArgs> UpdateFailed;
|
||||
public event EventHandler<EventArgs> Initialized;
|
||||
|
||||
public IStockDataService Service { get; set; }
|
||||
public bool IsOnline { get { return networkMonitor.IsInternetAvaliable; } }
|
||||
public int CurrentPriceIndex { get; private set; }
|
||||
public string NetworkState { get { return IsOnline ? "Connected" : "Offline"; } }
|
||||
|
||||
public RealTimeDataModel() {
|
||||
networkMonitor = new NetworkMonitor();
|
||||
networkMonitor.InternetAvaliableChanged += OnInternetAvaliableChanged;
|
||||
executor = new Executor(networkMonitor);
|
||||
executor.ExecuteFailed += new EventHandler(OnExecuteFailed);
|
||||
transactions = new List<TransactionData>();
|
||||
comparer = new PriceAscedingComparer();
|
||||
rand = new Random();
|
||||
}
|
||||
void OnInternetAvaliableChanged(object sender, EventArgs e) {
|
||||
executor.Status = networkMonitor.IsInternetAvaliable == true ? ExecutorStatus.Enabled : ExecutorStatus.Offline;
|
||||
if (!isInitialized)
|
||||
InitServer();
|
||||
else
|
||||
{
|
||||
ChangeUserState();
|
||||
UpdateService();
|
||||
}
|
||||
}
|
||||
void RaiseInitialized() {
|
||||
if (this.Initialized != null)
|
||||
this.Initialized(this, EventArgs.Empty);
|
||||
}
|
||||
void RaiseUpdateFailed() {
|
||||
Service = CreateOfflineService();
|
||||
UpdateFailed(this, new RealTimeDataEventArgs(RemoteServerUnavailableMessage));
|
||||
}
|
||||
void OnExecuteFailed(object sender, EventArgs e) {
|
||||
RaiseUpdateFailed();
|
||||
}
|
||||
public void InitServer() {
|
||||
try {
|
||||
isInitialized = true;
|
||||
UpdateService();
|
||||
RaiseInitialized();
|
||||
}
|
||||
catch {
|
||||
RaiseUpdateFailed();
|
||||
}
|
||||
}
|
||||
public void UpdateService() {
|
||||
Service = CreateOfflineService();
|
||||
}
|
||||
void CorrectTransactionData() {
|
||||
if (transactions.Count > 30) {
|
||||
int transactionsCount = 0;
|
||||
if (CurrentPriceIndex > 0)
|
||||
transactionsCount = transactions.Count - CurrentPriceIndex;
|
||||
bool isDominating = transactionsCount > (transactions.Count - transactionsCount) ? true : false;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
CurrentPriceIndex--;
|
||||
if (isDominating)
|
||||
transactions.RemoveAt(0);
|
||||
else
|
||||
transactions.RemoveAt(transactions.Count - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
void CorrectOnOneTransactionTypeExists() {
|
||||
if (CurrentPriceIndex == -1 && transactions.Count != 0) {
|
||||
int lastIndex = transactions.Count - 1;
|
||||
string transantionType = transactions[0].Bid == 0 ? "Bid" : "Ask";
|
||||
int volume = transactions[lastIndex].Volume + 5;
|
||||
double price;
|
||||
if (comparer.GetType() == typeof(PriceAscedingComparer))
|
||||
price = IsDownMoving(transantionType) ? transactions[lastIndex].Price + 0.5 : transactions[0].Price - 0.5;
|
||||
else
|
||||
price = IsDownMoving(transantionType) ? transactions[lastIndex].Price - 0.5 : transactions[0].Price + 0.5;
|
||||
TransactionData tdvm = new TransactionData(transantionType, volume, price);
|
||||
transactions.Add(tdvm);
|
||||
CurrentPriceIndex = transactions.IndexOf(tdvm);
|
||||
}
|
||||
}
|
||||
void CheckTransactions(int currentIndex, double price, string trantctionType) {
|
||||
bool isDownMoving = IsDownMoving(trantctionType);
|
||||
int index = isDownMoving ? 1 : -1;
|
||||
int i = currentIndex + index;
|
||||
while ((i < transactions.Count && i > -1) && transactions[i].TransactionType != transactions[currentIndex].TransactionType) {
|
||||
int delta = transactions[currentIndex].Volume - transactions[i].Volume;
|
||||
if (delta == 0) {
|
||||
if (isDownMoving) {
|
||||
transactions.Remove(transactions[i]);
|
||||
transactions.Remove(transactions[currentIndex]);
|
||||
}
|
||||
else {
|
||||
transactions.Remove(transactions[currentIndex]);
|
||||
transactions.Remove(transactions[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (delta < 0) {
|
||||
transactions[i].Volume = -delta;
|
||||
transactions.Remove(transactions[currentIndex]);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
transactions[currentIndex].Volume = delta;
|
||||
transactions.Remove(transactions[i]);
|
||||
if (!isDownMoving) { currentIndex--; i--; }
|
||||
}
|
||||
}
|
||||
}
|
||||
void AddNewTransaction(double currentPrice, string transactionType) {
|
||||
int maxVolumeValue = 100;
|
||||
double price = GetNewTransactionPrice(currentPrice);
|
||||
int volume = 1 + rand.Next(maxVolumeValue);
|
||||
TransactionData currentTransaction = new TransactionData(transactionType, volume, price);
|
||||
transactions.Add(currentTransaction);
|
||||
transactions.Sort(comparer);
|
||||
CheckTransactions(transactions.IndexOf(currentTransaction), price, transactionType);
|
||||
}
|
||||
int FindNewCurrentPriceIndex() {
|
||||
for (int i = 0; i < transactions.Count; i++) {
|
||||
if (i < transactions.Count - 1 && transactions[i].TransactionType != transactions[i + 1].TransactionType)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
bool IsDownMoving(string trantctionType) {
|
||||
Type type = comparer.GetType();
|
||||
return type == typeof(PriceAscedingComparer) && trantctionType == "Bid";
|
||||
}
|
||||
double GetNewTransactionPrice(double currentPrice) {
|
||||
double factor = currentPrice * 0.1 * rand.NextDouble();
|
||||
factor = rand.NextDouble() > 0.5 ? factor : -factor;
|
||||
double price = currentPrice + factor;
|
||||
return Math.Round(price, 2);
|
||||
}
|
||||
IStockDataService CreateOfflineService() {
|
||||
return offlineService ?? (offlineService = new StockDataOfflineService());
|
||||
}
|
||||
public void ChangeUserState() {
|
||||
executor.ChangeUserID();
|
||||
}
|
||||
public void ClearTransactions() {
|
||||
transactions.Clear();
|
||||
}
|
||||
public List<TransactionData> GetTransactions(double currentPrice) {
|
||||
int maxTransactionCount = 3;
|
||||
int numOfTransactions = 1 + rand.Next(maxTransactionCount);
|
||||
for(int i = 0; i < numOfTransactions; i++) {
|
||||
AddNewTransaction(currentPrice, "Bid");
|
||||
AddNewTransaction(currentPrice, "Ask");
|
||||
}
|
||||
CurrentPriceIndex = FindNewCurrentPriceIndex();
|
||||
CorrectTransactionData();
|
||||
CorrectOnOneTransactionTypeExists();
|
||||
return transactions;
|
||||
}
|
||||
}
|
||||
}
|
||||
417
StockMarketTraderApp/Model/StockDataOfflineProvider.cs
Normal file
417
StockMarketTraderApp/Model/StockDataOfflineProvider.cs
Normal file
@@ -0,0 +1,417 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user