mirror of
https://github.com/DevExpress/netcore-winforms-demos.git
synced 2025-12-23 01:48:33 +00:00
678 lines
32 KiB
C#
678 lines
32 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Windows;
|
|
using System.Windows.Forms;
|
|
using DevExpress.StockMarketTrader.Model;
|
|
using DevExpress.StockMarketTrader.Model.BusinessObjects;
|
|
using DevExpress.StockMarketTrader.StockDataServiceReference;
|
|
using Application = System.Windows.Forms.Application;
|
|
|
|
namespace DevExpress.StockMarketTrader.ViewModel {
|
|
public class RealTimeDataViewModel : ViewModelBase {
|
|
public static bool IsReady = false;
|
|
protected static void InvokeSync(Delegate method) {
|
|
if (method != null && Application.OpenForms.Count > 0) {
|
|
for(int i = 0; i < Application.OpenForms.Count; i++) {
|
|
Form form = Application.OpenForms[i];
|
|
if(form is StockMarketView)
|
|
form.Invoke(method, new object[] { });
|
|
}
|
|
}
|
|
}
|
|
|
|
object sem = new object();
|
|
string selectedCompanyName = "MSFT";
|
|
int volumeCount = 15;
|
|
int countOfWeek = 1;
|
|
int candlesCount = 72, currentDate = 0, tickCount = 0, offlineTimeInterval = 500, totalTicks = 5;
|
|
bool isAllBindingDataUpdate = false, canEndUpdate = true, canUpdate = true;
|
|
double highestPrice = 0, lowestPrice = 0;
|
|
public RealTimeDataModel model;
|
|
Dictionary<string, Queue<Delegate>> defferedUpdate = new Dictionary<string, Queue<Delegate>>();
|
|
List<DateTime> dates;
|
|
List<string> companies;
|
|
LockableCollection<TransactionData> transactionGridBindingData;
|
|
LockableCollection<CompanyTradingDataViewModel> watchLisBindingData;
|
|
BindingList<CompaniesVolumeData> volumeChartBindingData;
|
|
BindingList<TradingDataViewModel> stockChartBindingData;
|
|
CompanyTradingDataViewModel selectedCompany;
|
|
ObservableCollection<CompanyTradingDataViewModel> oldWatchListData;
|
|
LiveTileViewModel sparklineTileViewModel = new LiveTileViewModel();
|
|
List<LiveTileViewModel> topThreeCompanies = new List<LiveTileViewModel>() { new LiveTileViewModel(), new LiveTileViewModel(), new LiveTileViewModel() };
|
|
|
|
EventHandler currentPriceIndexChanged;
|
|
EventHandler watchListChanged;
|
|
|
|
public event EventHandler CurrentPriceIndexChanged { add { currentPriceIndexChanged += value; } remove { currentPriceIndexChanged -= value; } }
|
|
public event EventHandler WatchListChanged { add { watchListChanged += value; } remove { watchListChanged -= value; } }
|
|
|
|
|
|
Timer TimerCore { get; set; }
|
|
public int CurrentPriceIndex { get; set; }
|
|
public int Ticks {
|
|
get { return totalTicks; }
|
|
set { totalTicks = value; }
|
|
}
|
|
public int TickCount {
|
|
get { return tickCount; }
|
|
set { tickCount = value; } }
|
|
public int CandlesCount {
|
|
get { return candlesCount; }
|
|
set { candlesCount = value; }
|
|
}
|
|
public bool IsSuspendUpdating { get; set; }
|
|
public bool IsLoading { get; set; }
|
|
public string NetworkState { get { return model.NetworkState; } }
|
|
public CompanyTradingDataViewModel SelectedCompany {
|
|
get { return selectedCompany; }
|
|
set {
|
|
if (value != null) {
|
|
if(selectedCompanyName != value.CompanyName || selectedCompany != value) {
|
|
List<CompanyTradingDataViewModel> result = watchLisBindingData.Where(e => e.CompanyName == value.CompanyName).Select(e => e).ToList();
|
|
if (result.Count > 0) {
|
|
selectedCompanyName = value.CompanyName;
|
|
selectedCompany = result[0];
|
|
SetSelectedCompany();
|
|
}
|
|
}
|
|
}
|
|
OnPropertyChanged("SelectedCompany");
|
|
}
|
|
}
|
|
public LiveTileViewModel SparklineTileViewModel {
|
|
get { return sparklineTileViewModel; }
|
|
set { sparklineTileViewModel = value; OnPropertyChanged("SparklineTileViewModel"); }
|
|
}
|
|
public List<LiveTileViewModel> TopThreeCompanies {
|
|
get { return topThreeCompanies; }
|
|
set { topThreeCompanies = value; OnPropertyChanged("TopThreeCompanies"); }
|
|
}
|
|
public LockableCollection<CompanyTradingDataViewModel> WatchListBindingData { get { return watchLisBindingData; } }
|
|
public BindingList<TradingDataViewModel> StockChartBindingData { get { return stockChartBindingData; } }
|
|
public LockableCollection<TransactionData> TransactionGridBindingData { get { return transactionGridBindingData; } }
|
|
public BindingList<CompaniesVolumeData> VolumeChartBindingData { get { return volumeChartBindingData; } }
|
|
|
|
public RealTimeDataViewModel(Timer timer) {
|
|
TimerCore = timer;
|
|
TimerCore.Interval = offlineTimeInterval;
|
|
TimerCore.Tick += new EventHandler(UpdateOnTimer);
|
|
|
|
model = new RealTimeDataModel();
|
|
model.UpdateFailed += new EventHandler<RealTimeDataEventArgs>(OnUpdateFailed);
|
|
model.Initialized += new EventHandler<EventArgs>(OnInitialized);
|
|
stockChartBindingData = new BindingList<TradingDataViewModel>();
|
|
watchLisBindingData = new LockableCollection<CompanyTradingDataViewModel>();
|
|
transactionGridBindingData = new LockableCollection<TransactionData>();
|
|
volumeChartBindingData = new BindingList<CompaniesVolumeData>();
|
|
|
|
IsLoading = true;
|
|
}
|
|
void OnInitialized(object sender, EventArgs e) {
|
|
GetDatesAsync();
|
|
}
|
|
void OnUpdateFailed(object sender, RealTimeDataEventArgs e) {
|
|
}
|
|
void OnCandlesCountChangedCallBack() {
|
|
CorrectCurrentDate();
|
|
tickCount = 0;
|
|
candlesCount = CandlesCount + 1;
|
|
StopTimer();
|
|
UpdateAllBindingData();
|
|
}
|
|
void CorrectCurrentDate() {
|
|
int delta = currentDate;
|
|
delta = currentDate - (CandlesCount + 1) * Ticks;
|
|
if (delta > -1)
|
|
currentDate = delta;
|
|
else {
|
|
delta = currentDate - candlesCount * totalTicks;
|
|
currentDate = delta < 0 ? 0 : delta;
|
|
}
|
|
}
|
|
//void ChangeTimerInterval(int time) {
|
|
// TimerCore.Interval = time;
|
|
//}
|
|
void StartTimer() {
|
|
InvokeSync(new Action(() => { TimerCore.Start(); }));
|
|
}
|
|
void StopTimer() {
|
|
InvokeSync(new Action(() => { TimerCore.Stop(); }));
|
|
}
|
|
void GetDatesAsync() {
|
|
SetDates(model.Service.GetDates());
|
|
//Action<DateTime[]> action = new Action<DateTime[]>(SetDates);
|
|
//AddDefferedDelegate("GetDates", action);
|
|
//model.BeginGetDates();
|
|
}
|
|
void SetDates(DateTime[] dates) {
|
|
try {
|
|
if (dates.Length == 0)
|
|
throw new Exception();
|
|
this.dates = new List<DateTime>(dates);
|
|
GetCompaniesAsync();
|
|
canEndUpdate = true;
|
|
}
|
|
catch {
|
|
canUpdate = false;
|
|
}
|
|
}
|
|
void InitializeChartBindingData() {
|
|
isAllBindingDataUpdate = true;
|
|
stockChartBindingData.Clear();
|
|
}
|
|
void GetCompaniesAsync() {
|
|
SetCompanies(model.Service.GetCompaniesName());
|
|
}
|
|
void SetCompanies(string[] arrayCompanies) {
|
|
if(model.IsOnline) {
|
|
this.companies = new List<string>();
|
|
for(int i = 0; i < arrayCompanies.Length; i++)
|
|
this.companies.Add(arrayCompanies[i]);
|
|
}
|
|
else
|
|
this.companies = new List<string>(arrayCompanies);
|
|
InitializeChartBindingData();
|
|
GetBindingDataAsync();
|
|
}
|
|
void GetVolumeDynamicsDataAsyncCompleted2(StockData[] data) { }
|
|
void GetBindingDataAsync() {
|
|
GetWatchListBindingDataAsync();
|
|
GetCompaniesVolumeAsync();
|
|
currentDate = 0;
|
|
|
|
GetVolumeDynamicsDataAsync();
|
|
GetStockChartBindingDataAsync();
|
|
}
|
|
void GetVolumeDynamicsDataAsync(int current = 0) {
|
|
if (companies == null) return;
|
|
int date = current + totalTicks * ((candlesCount - volumeCount) + 1);
|
|
GetVolumeDynamicsDataAsyncCompleted(model.Service.GetStockDataFromPeriodByCompanyList(date, volumeCount, totalTicks, companies.ToArray()));
|
|
}
|
|
void GetVolumeDynamicsDataAsyncCompleted(CompanyStockData[] cd) {
|
|
foreach (CompanyStockData companyStockData in cd) {
|
|
CompanyTradingDataViewModel vm = watchLisBindingData.Where(c => c.CompanyName == companyStockData.CompanyName).Select(c => c).FirstOrDefault();
|
|
vm.VolumeDynamics = CreateVolumeDynamicsBindingData(companyStockData.Data);
|
|
}
|
|
TryEndUpdateBindingData();
|
|
}
|
|
void GetWatchListBindingDataAsync() {
|
|
currentDate += candlesCount * totalTicks;
|
|
UpdateWatchListBindingDataAsyncCompleted(model.Service.GetStockDataByDate(dates[currentDate - 1]));
|
|
}
|
|
void GetStockChartBindingDataAsync() {
|
|
GetStockChartBindingDataAsyncCompleted(model.Service.GetCompanyMultipleDataFromPeriod(currentDate, candlesCount, totalTicks, selectedCompanyName));
|
|
}
|
|
void GetStockChartBindingDataAsyncCompleted(CompanyData[] data) {
|
|
List<CompanyData> newStockChartData = new List<CompanyData>();
|
|
try {
|
|
newStockChartData = new List<CompanyData>(data);
|
|
}
|
|
catch { }
|
|
AddChartPoints(newStockChartData);
|
|
}
|
|
void AddChartPoints(List<CompanyData> newStockChartData) {
|
|
CreateChartBindingData(newStockChartData);
|
|
UpdateSparklineViewModelSource();
|
|
isAllBindingDataUpdate = false;
|
|
TryEndUpdateBindingData();
|
|
}
|
|
void UpdateSparklineViewModelSource() {
|
|
SparklineTileViewModel.Source = stockChartBindingData;
|
|
}
|
|
void UpdateWatchListBindingDataAsync() {
|
|
if (dates == null) return;
|
|
if(currentDate >= 0 && currentDate < dates.Count)
|
|
UpdateWatchListBindingDataAsyncCompleted(model.Service.GetStockDataByDate(dates[currentDate]));
|
|
else
|
|
UpdateWatchListBindingDataAsyncCompleted(model.Service.GetStockDataByDate(dates.FirstOrDefault()));
|
|
}
|
|
void UpdateCompaniesVolumeAsync() {
|
|
if (tickCount == totalTicks || tickCount == 0)
|
|
GetCompaniesVolumeAsync();
|
|
}
|
|
void UpdateWatchListBindingDataAsyncCompleted(StockData[] gridData) {
|
|
UpdateWatchList(gridData);
|
|
UpdateSparklineViewModelCompany();
|
|
UpdateTopThreeCompany();
|
|
TryEndUpdateBindingData();
|
|
}
|
|
void UpdateTopThreeCompany() {
|
|
var topThree = GetTopThreeVolume();
|
|
if (topThree.Count < 3) return;
|
|
var result = new List<LiveTileViewModel>();
|
|
foreach (CompaniesVolumeData volumeData in topThree) {
|
|
LiveTileViewModel vm = new LiveTileViewModel();
|
|
vm.CompanyIndex = volumeData.CompanyName;
|
|
double delta = 0;
|
|
double increace = CalcIncrease(volumeData.CompanyName, ref delta);
|
|
vm.Arrow = increace > 0 ? "▲" : "▼";
|
|
vm.Persent = Math.Abs(increace) * 100 + "%";
|
|
vm.PriceIncrease = Math.Abs(Math.Round(delta, 3)).ToString();
|
|
result.Add(vm);
|
|
}
|
|
TopThreeCompanies = result;
|
|
}
|
|
void GetCompaniesVolumeAsync() {
|
|
int endIndex = currentDate - totalTicks;
|
|
if (dates != null && currentDate < dates.Count && endIndex > 0) {
|
|
DateTime start = dates[currentDate];
|
|
DateTime end = dates[endIndex];
|
|
GetCompaniesVolumeCompleted(model.Service.GetCompaniesVolumeFromPeriod(start, end));
|
|
}
|
|
}
|
|
void GetCompaniesVolumeCompleted(CompaniesVolumeData[] data) {
|
|
UpdateVolumeChartBindingData(data);
|
|
}
|
|
void UpdateVolumeChartBindingData(CompaniesVolumeData[] data) {
|
|
volumeChartBindingData.Clear();
|
|
SetVolumeOfSelectedCompany();
|
|
int index = 1;
|
|
for (int i = 0; i < data.Length - 1; i++) {
|
|
if (data[i].CompanyName == selectedCompanyName)
|
|
continue;
|
|
if (volumeChartBindingData.Count < data.Length + 1)
|
|
volumeChartBindingData.Add(data[i]);
|
|
index++;
|
|
}
|
|
ValidateCompaniesVolume();
|
|
TryEndUpdateBindingData();
|
|
}
|
|
void UpdateSparklineViewModelCompany() {
|
|
SparklineTileViewModel.CompanyIndex = SelectedCompany?.CompanyName;
|
|
double delta = 0;
|
|
double increace = CalcIncrease(SelectedCompany?.CompanyName, ref delta);
|
|
SparklineTileViewModel.Arrow = increace > 0 ? "▲" : "▼";
|
|
SparklineTileViewModel.Persent = Math.Abs(increace) * 100 + "%";
|
|
}
|
|
void ValidateCompaniesVolume() {
|
|
List<string> volumeCompanies = volumeChartBindingData.Select(c => c.CompanyName).ToList();
|
|
List<string> exceptCompanies = companies.Except(volumeCompanies).ToList();
|
|
for (int i = 0; i < volumeChartBindingData.Count; i++) {
|
|
CompaniesVolumeData volumeData = volumeChartBindingData[i];
|
|
if (!companies.Contains(volumeData.CompanyName)) {
|
|
var res = watchLisBindingData.Where(c => exceptCompanies.Contains(c.CompanyName)).ToList();
|
|
if (res.Count > 0) {
|
|
double maxVolume = res.Max(c => c.Volume);
|
|
CompanyTradingDataViewModel vm = watchLisBindingData.Where(c => c.Volume == maxVolume).Select(c => c).FirstOrDefault();
|
|
exceptCompanies.Remove(vm.CompanyName);
|
|
volumeChartBindingData[i] = new CompaniesVolumeData() {
|
|
CompanyName = vm.CompanyName,
|
|
Volume = (int)maxVolume
|
|
};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
void SetVolumeOfSelectedCompany() {
|
|
if (volumeChartBindingData.Count == 0 && SelectedCompany != null) {
|
|
CompaniesVolumeData cvd = new CompaniesVolumeData();
|
|
cvd.CompanyName = SelectedCompany.CompanyName;
|
|
cvd.Volume = (int)SelectedCompany.Volume;
|
|
volumeChartBindingData.Add(cvd);
|
|
}
|
|
else if (SelectedCompany != null) {
|
|
volumeChartBindingData[0].CompanyName = SelectedCompany.CompanyName;
|
|
volumeChartBindingData[0].Volume = (int)SelectedCompany.Volume;
|
|
}
|
|
}
|
|
void TryEndUpdateBindingData() {
|
|
if (canEndUpdate)
|
|
EndUpdateBindingData();
|
|
}
|
|
void EndUpdateBindingData() {
|
|
if (!TimerCore.Enabled && !isAllBindingDataUpdate)
|
|
StartTimer();
|
|
}
|
|
void UpdateOnTimer(object sender, EventArgs e) {
|
|
if (!IsSuspendUpdating)
|
|
UpdateData();
|
|
}
|
|
void UpdateAllBindingData(bool needUpdateVolumeDynamics = true) {
|
|
if (canUpdate) {
|
|
InitProperties();
|
|
model.ChangeUserState();
|
|
defferedUpdate.Clear();
|
|
tickCount = 0;
|
|
if (needUpdateVolumeDynamics)
|
|
GetVolumeDynamicsDataAsync(currentDate);
|
|
|
|
UpdateCompaniesVolumeAsync();
|
|
UpdateWatchListBindingDataAsync();
|
|
|
|
InitializeChartBindingData();
|
|
GetStockChartBindingDataAsync();
|
|
}
|
|
}
|
|
void UpdateData() {
|
|
lock (sem) {
|
|
int dateLocal = currentDate;
|
|
if (dates == null || dateLocal < 0 || dateLocal > dates.Count -1) return;
|
|
StopTimer();
|
|
DateTime date = dates[dateLocal];
|
|
switch (totalTicks) {
|
|
case 5:
|
|
RemoveOldCompanyStockChart(date, 1);
|
|
break;
|
|
case 10:
|
|
RemoveOldCompanyStockChart(date, 2);
|
|
break;
|
|
case 20:
|
|
RemoveOldCompanyStockChart(date, 4);
|
|
break;
|
|
}
|
|
UpdateBindingData();
|
|
}
|
|
}
|
|
void RemoveOldCompanyStockChart(DateTime date, int count) {
|
|
if (date.DayOfWeek == DayOfWeek.Monday && countOfWeek == count) {
|
|
tickCount = 0;
|
|
if (stockChartBindingData != null && stockChartBindingData.Count > 1) stockChartBindingData.Remove(stockChartBindingData[0]);
|
|
foreach (CompanyTradingDataViewModel vm in watchLisBindingData) {
|
|
if (vm.VolumeDynamics != null && ((IList)vm.VolumeDynamics).Count > 0)
|
|
((IList)vm.VolumeDynamics).RemoveAt(0);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
void UpdateBindingData() {
|
|
UpdateStockChartBindingDataAsync();
|
|
UpdateWatchListBindingDataAsync();
|
|
UpdateCompaniesVolumeAsync();
|
|
UpdateVolumeDynamicsAsync();
|
|
UpdateTransactionBindingData();
|
|
}
|
|
void UpdateVolumeDynamicsAsync() {
|
|
if (companies != null)
|
|
UpdateVolumeDynamicsAsyncCompleted(model.Service.GetStockDataFromDateByCompanyList(dates[currentDate], companies.ToArray()));
|
|
}
|
|
void UpdateVolumeDynamicsAsyncCompleted(CompanyStockData[] cd) {
|
|
foreach (CompanyStockData companynStockData in cd) {
|
|
try {
|
|
if (companynStockData.Data.Length == 0) continue;
|
|
DateTime current = dates[currentDate];
|
|
CompanyTradingData ctd = GetCompanyTradingData(companynStockData.Data[0], current);
|
|
CompanyTradingDataViewModel vm = watchLisBindingData.Where(c => c.CompanyName == companynStockData.CompanyName).Select(c => c).FirstOrDefault();
|
|
if (vm == null) continue;
|
|
IList<TradingDataViewModel> volDyn = vm.VolumeDynamics as IList<TradingDataViewModel>;
|
|
|
|
if (vm.VolumeDynamics == null || ((IList)vm.VolumeDynamics).Count == 0) return;
|
|
if (tickCount == 2) {
|
|
ctd.Volume = Math.Round((ctd.Volume / 1000000), 2);
|
|
volDyn.Add(new TradingDataViewModel(ctd));
|
|
}
|
|
if (tickCount != 2) {
|
|
TradingDataViewModel tdvm = new TradingDataViewModel(volDyn[volDyn.Count - 1].TradingData);
|
|
tdvm.Volume = Math.Round((ctd.Volume / 1000000), 2);
|
|
tdvm.Close = ctd.Close;
|
|
tdvm.Low = lowestPrice;
|
|
tdvm.High = highestPrice;
|
|
tdvm.Price = ctd.Price;
|
|
volDyn[volDyn.Count - 1] = tdvm;
|
|
}
|
|
}
|
|
catch {
|
|
currentDate++;
|
|
UpdateStockChartBindingDataAsync();
|
|
}
|
|
}
|
|
TryEndUpdateBindingData();
|
|
}
|
|
void UpdateStockChartBindingDataAsync() {
|
|
UpdateStockChartBindingDataAsyncCompleted(model.Service.GetCompanyStockData(dates[currentDate], selectedCompanyName));
|
|
}
|
|
void UpdateStockChartBindingDataAsyncCompleted(StockData[] data) {
|
|
if (data.Length == 0) {
|
|
IncrementDateAndUpdateStockChartBindingData();
|
|
}
|
|
else {
|
|
try {
|
|
UpdateStockChart(data[0]);
|
|
UpdateSparklineViewModelSource();
|
|
TryEndUpdateBindingData();
|
|
}
|
|
catch {
|
|
IncrementDateAndUpdateStockChartBindingData();
|
|
}
|
|
}
|
|
}
|
|
void IncrementDateAndUpdateStockChartBindingData() {
|
|
currentDate++;
|
|
UpdateStockChartBindingDataAsync();
|
|
}
|
|
void UpdateStockChart(StockData newChartData) {
|
|
tickCount++;
|
|
DateTime current = dates[currentDate];
|
|
CompanyTradingData ctd = GetCompanyTradingData(newChartData, current);
|
|
switch (totalTicks) {
|
|
case 5:
|
|
AddStockChart(current, ctd, 1);
|
|
break;
|
|
case 10:
|
|
AddStockChart(current, ctd, 2);
|
|
break;
|
|
default:
|
|
AddStockChart(current, ctd, 4);
|
|
break;
|
|
}
|
|
currentDate++;
|
|
}
|
|
void AddStockChart(DateTime current, CompanyTradingData ctd, int count) {
|
|
if (current.DayOfWeek == DayOfWeek.Monday && countOfWeek == count) {
|
|
ctd.Volume = Math.Round((ctd.Volume / 1000000), 2);
|
|
stockChartBindingData.Add(new TradingDataViewModel(ctd));
|
|
highestPrice = ctd.High;
|
|
lowestPrice = ctd.Low;
|
|
countOfWeek = 1;
|
|
return;
|
|
}
|
|
if (current.DayOfWeek == DayOfWeek.Monday && countOfWeek != count) {
|
|
SetStockChartBindingData(ctd);
|
|
countOfWeek++;
|
|
return;
|
|
}
|
|
if (current.DayOfWeek != DayOfWeek.Monday) SetStockChartBindingData(ctd);
|
|
}
|
|
void TryResetCurrentDate() {
|
|
if (dates != null && currentDate + totalTicks > dates.Count - 1) {
|
|
currentDate = 0;
|
|
tickCount = 0;
|
|
}
|
|
}
|
|
void CreateChartBindingData(List<CompanyData> newStockChartData) {
|
|
TryResetCurrentDate();
|
|
int index = 0;
|
|
DateTime firstDate = newStockChartData[0].Data.Date;
|
|
DateTime startDate = new DateTime(firstDate.Year, firstDate.Month, 1);
|
|
foreach (CompanyData candleData in newStockChartData) {
|
|
CompanyTradingData ctd = new CompanyTradingData(candleData.Data, "");
|
|
ctd.Close = candleData.ClosePrice;
|
|
ctd.Volume = Math.Round(((double)ctd.Volume / 1000000), 2);
|
|
ctd.Low = lowestPrice = candleData.LowPrice;
|
|
ctd.High = highestPrice = candleData.HighPrice;
|
|
TradingDataViewModel viewModel = new TradingDataViewModel(ctd) { Date = startDate };
|
|
if (stockChartBindingData.Count < candlesCount) {
|
|
stockChartBindingData.Add(viewModel);
|
|
}
|
|
else
|
|
stockChartBindingData[index] = viewModel;
|
|
startDate = UpdateDate(startDate, true);
|
|
index++;
|
|
}
|
|
DateTime search = UpdateDate(startDate, false);
|
|
while (true) {
|
|
int dateIndex = dates.IndexOf(search);
|
|
if (dateIndex != -1) {
|
|
currentDate = dateIndex;
|
|
break;
|
|
}
|
|
search = search.AddDays(-1);
|
|
}
|
|
}
|
|
void UpdateWatchList(StockData[] watchListData) {
|
|
int count = 0;
|
|
int isRise = 0;
|
|
oldWatchListData = new ObservableCollection<CompanyTradingDataViewModel>(watchLisBindingData as IEnumerable<CompanyTradingDataViewModel>);
|
|
oldWatchListData = new ObservableCollection<CompanyTradingDataViewModel>();
|
|
foreach (CompanyTradingDataViewModel item in watchLisBindingData) {
|
|
oldWatchListData.Add(new CompanyTradingDataViewModel(item.TradingData, item.CompanyName, item.Rise, item.TotalRise));
|
|
}
|
|
watchLisBindingData.BeginUpdate();
|
|
foreach (StockData dt in watchListData) {
|
|
if (companies.Count <= (dt.CompanyID)) continue;
|
|
CompanyTradingData ctd = new CompanyTradingData(dt, companies[dt.CompanyID]);
|
|
if (watchLisBindingData.Count < companies.Count)
|
|
watchLisBindingData.Add(new CompanyTradingDataViewModel(ctd, ctd.CompanyName, isRise, 1));
|
|
else {
|
|
SetWatchListBindingData(count, ctd);
|
|
count++;
|
|
}
|
|
}
|
|
watchLisBindingData.EndUpdate();
|
|
if (watchListChanged != null)
|
|
watchListChanged(this, EventArgs.Empty);
|
|
}
|
|
void SetWatchListBindingData(int index, CompanyTradingData ctd) {
|
|
watchLisBindingData[index].Rise = 0;
|
|
if (ctd.Price > watchLisBindingData[index].Price) {
|
|
watchLisBindingData[index].TotalRise = Math.Min(0.5 + (1 - watchLisBindingData[index].Price / ctd.Price) * 10, 1.3);
|
|
watchLisBindingData[index].Rise = 180;
|
|
}
|
|
else if (ctd.Price < watchLisBindingData[index].Price) {
|
|
watchLisBindingData[index].TotalRise = Math.Min(0.5 + (1 - ctd.Price / watchLisBindingData[index].Price) * 10, 1.3);
|
|
watchLisBindingData[index].Rise = -180;
|
|
}
|
|
watchLisBindingData[index].Assign(ctd);
|
|
}
|
|
void SetStockChartBindingData(CompanyTradingData ctd)
|
|
{
|
|
TradingDataViewModel tdvm = null;
|
|
if (stockChartBindingData.Count > 0)
|
|
tdvm = new TradingDataViewModel(stockChartBindingData[stockChartBindingData.Count - 1].TradingData);
|
|
else
|
|
tdvm = new TradingDataViewModel();
|
|
highestPrice = Math.Max(highestPrice, ctd.High);
|
|
lowestPrice = Math.Min(lowestPrice, ctd.Low);
|
|
tdvm.Volume = Math.Round((ctd.Volume / 1000000), 2);
|
|
tdvm.Close = ctd.Close;
|
|
tdvm.Low = lowestPrice;
|
|
tdvm.High = highestPrice;
|
|
tdvm.Price = ctd.Price;
|
|
if (stockChartBindingData.Count > 0)
|
|
stockChartBindingData[stockChartBindingData.Count - 1] = tdvm;
|
|
else
|
|
stockChartBindingData.Add(tdvm);
|
|
}
|
|
void UpdateTransactionBindingData() {
|
|
TryResetCurrentDate();
|
|
if (stockChartBindingData.Count < 1) return;
|
|
List<TransactionData> transactions = model.GetTransactions(stockChartBindingData[stockChartBindingData.Count - 1].Price);
|
|
SetTransactionGridBindingData(transactions);
|
|
IsLoading = false;
|
|
OnPropertyChanged("IsLoading");
|
|
}
|
|
void SetTransactionGridBindingData(List<TransactionData> transactions) {
|
|
transactionGridBindingData.Clear();
|
|
transactionGridBindingData.BeginUpdate();
|
|
foreach (TransactionData tdvm in transactions) {
|
|
transactionGridBindingData.Add(tdvm);
|
|
}
|
|
transactionGridBindingData.EndUpdate();
|
|
CurrentPriceIndex = model.CurrentPriceIndex;
|
|
RaiseCurrentPriceIndexChanged();
|
|
}
|
|
void RaiseCurrentPriceIndexChanged() {
|
|
if (currentPriceIndexChanged != null)
|
|
currentPriceIndexChanged(this, EventArgs.Empty);
|
|
}
|
|
void SetSelectedCompany() {
|
|
StopTimer();
|
|
int delta = currentDate - candlesCount * totalTicks;
|
|
currentDate = delta < 0 ? 0 : delta;
|
|
UpdateAllBindingData(true);
|
|
}
|
|
void InitProperties() {
|
|
TryResetCurrentDate();
|
|
isAllBindingDataUpdate = true;
|
|
IsLoading = true;
|
|
model.ClearTransactions();
|
|
OnPropertyChanged("IsLoading");
|
|
}
|
|
double CalcIncrease(string company, ref double delta) {
|
|
var companyData = watchLisBindingData.Where(c => c.CompanyName == company).Select(c => c).FirstOrDefault();
|
|
var oldCompanyData = oldWatchListData.Where(c => c.CompanyName == company).Select(c => c).FirstOrDefault();
|
|
if (companyData != null && oldCompanyData != null) {
|
|
double newPrice = companyData.Price;
|
|
double oldPrice = oldCompanyData.Price;
|
|
delta = newPrice - oldPrice;
|
|
return Math.Round(delta / newPrice, 3);
|
|
}
|
|
return 0;
|
|
}
|
|
CompanyTradingData GetCompanyTradingData(StockData newData, DateTime current) {
|
|
CompanyTradingData ctd = new CompanyTradingData(newData, "");
|
|
return ctd;
|
|
}
|
|
DateTime UpdateDate(DateTime startDate, bool add) {
|
|
DateTime returnDate = new DateTime();
|
|
switch (totalTicks) {
|
|
case 1:
|
|
if (add) startDate = startDate.AddDays(1);
|
|
if (!add) returnDate = startDate.AddDays(-1);
|
|
break;
|
|
case 5:
|
|
if (add) startDate = startDate.AddDays(7);
|
|
if (!add) returnDate = startDate.AddDays(-7);
|
|
break;
|
|
case 10:
|
|
if (add) startDate = startDate.AddDays(14);
|
|
if (!add) returnDate = startDate.AddDays(-14);
|
|
break;
|
|
case 20:
|
|
if (add) startDate = startDate.AddMonths(1);
|
|
if (!add) returnDate = startDate.AddMonths(-1);
|
|
break;
|
|
}
|
|
if (add) return startDate;
|
|
return returnDate;
|
|
}
|
|
Delegate GetDefferedDelegate(string key) {
|
|
if (defferedUpdate.ContainsKey(key) && defferedUpdate[key].Count != 0)
|
|
return defferedUpdate[key].Dequeue();
|
|
return null;
|
|
|
|
}
|
|
List<CompaniesVolumeData> GetTopThreeVolume() {
|
|
List<CompaniesVolumeData> result = new List<CompaniesVolumeData>();
|
|
if (volumeChartBindingData != null && volumeChartBindingData.Count > 0) {
|
|
for (int i = 0; i < 3; i++)
|
|
if (volumeChartBindingData.Count >= i + 1)
|
|
result.Add(volumeChartBindingData[i]);
|
|
}
|
|
return result;
|
|
}
|
|
LockableCollection<TradingDataViewModel> CreateVolumeDynamicsBindingData(StockData[] data) {
|
|
LockableCollection<TradingDataViewModel> result = new LockableCollection<TradingDataViewModel>();
|
|
foreach (StockData currentData in data) {
|
|
CompanyTradingData ctd = new CompanyTradingData(currentData, "");
|
|
ctd.Close = double.Parse(currentData.CloseP.ToString());
|
|
ctd.Volume = Math.Round(((double)ctd.Volume / 1000000), 2);
|
|
ctd.Low = double.Parse(currentData.LowP.ToString());
|
|
ctd.High = double.Parse(currentData.HighP.ToString());
|
|
result.Add(new TradingDataViewModel(ctd));
|
|
}
|
|
return result;
|
|
}
|
|
public void OnCandlesCountChanged() {
|
|
OnCandlesCountChangedCallBack();
|
|
}
|
|
public void SetTicks(int numberOfTicks) {
|
|
Ticks = numberOfTicks;
|
|
countOfWeek = 1;
|
|
}
|
|
}
|
|
}
|