using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Threading; using Easychart.Finance; using Easychart.Finance.DataProvider; using Easychart.Finance.Win; using GalaSoft.MvvmLight.Ioc; using Muchinfo.MTPClient.Data; using Muchinfo.MTPClient.Data.Enums; using Muchinfo.MTPClient.Data.Model; using Muchinfo.MTPClient.Data.Quote; using Muchinfo.MTPClient.Infrastructure.Utilities; using Muchinfo.MTPClient.IService; namespace Muchinfo.MTPClient.Analysis.Utilities { /// /// Class DataMananer. /// public class DataMananer : CacheDataManagerBase { #region Members of DataMananer (4) private const int c_defaultCount = 3; private ChartWinControl _winChart; private CycleType _cycleType; private DateTime BasicDateTime = new DateTime(1970, 1, 1, 0, 0, 0); // private IQuoteDataService _quoteDataService; private const short c_DefaultCount = 500; private QuoteGoods _currentGoods; //当前商品 private TimeSpan _timeSpan; private DateTime _quoteTime; //行情时间 private List _iDataPoints; private CommonDataProvider _commonDataProvider; //数据源 #endregion Members of DataMananer (4) #region Constructors of DataMananer (1) public DataMananer(ChartWinControl chart) { _quoteDataService = SimpleIoc.Default.GetInstance(); _winChart = chart; _commonDataProvider = new CommonDataProvider(this); ////可自定义首行显示格式 ////this._winChart.PriceLabelFormat = "{CODE} O:{OPEN} H:{HIGH} L:{LOW} C:{CLOSE} Chg:{CHANGE}"; _winChart.InsertFormulaToMain("MA4(5,10,20,30)"); _winChart.InsertDefaultFormula("MACD"); KeyMessageFilter.AddMessageFilter(_winChart); } #endregion Constructors of DataMananer (1) #region Methods of DataMananer (5) /// /// 转换周期 /// /// 周期类型 /// 分钟数据 /// 编辑器中的数据周期 private DataCycle ConvertCycle(CycleType cycleType, TimeSpan minutes) { switch (cycleType) { case CycleType.TimeSharing: return DataCycle.TimeChart; case CycleType.Minutes1: return DataCycle.Minute; case CycleType.Minutes5: return new DataCycle(DataCycleBase.MINUTE, 5); case CycleType.Minutes30: return new DataCycle(DataCycleBase.MINUTE, 30); case CycleType.Hour: return new DataCycle(DataCycleBase.HOUR, 1); case CycleType.Hour4: return new DataCycle(DataCycleBase.HOUR,4); case CycleType.Day: return new DataCycle(DataCycleBase.DAY, 1); default: return DataCycle.Day; } } /// /// Gets the data. /// /// The goods code. /// The count. /// IDataProvider. public override IDataProvider GetData(string goodsCode, int count) { if (_iDataPoints != null && _iDataPoints.Any()) { _commonDataProvider.LoadBinary(ConvertData(_iDataPoints)); _commonDataProvider.DataCycle = ConvertCycle(_cycleType, _timeSpan); _commonDataProvider.SetStringData("Code", goodsCode); } if (_iDataPoints == null || !_iDataPoints.Any()) //没数据时刷新会报异常 { return null; } return _commonDataProvider; } /// /// 初始化数据 /// /// 商品 /// 周期 /// 自定义周期 public void InitBarDataPoints(QuoteGoods goods, CycleType cycleType, TimeSpan timeSpan) { _currentGoods = goods; if (_iDataPoints != null) //删除前一周期数据 { _iDataPoints.Clear(); } CycleType = cycleType; _timeSpan = timeSpan; _winChart.DataManager = this; _winChart.DecimalPrice = goods.GoodsParameters.HqExchFigures; _winChart.CurrentDataCycle = ConvertCycle(_cycleType, _timeSpan); this._winChart.Symbol = goods.GoodsCode; //时间应该是服务器的时间 DateTime starTime = ApplicationParameter.ServerTimeNow; //取当前时间之前的 DateTime endTime = BasicDateTime; short count = c_DefaultCount; if (cycleType == CycleType.TimeSharing) { if (this._winChart.openCloseArray != null && this._winChart.openCloseArray.Length >= 2) { starTime = this._winChart.openCloseArray[0]; endTime = this._winChart.openCloseArray[this._winChart.openCloseArray.Length - 1]; count = 0; } } _quoteDataService.GetHistoryCycleData(goods, cycleType, starTime, endTime, count, QueryHistorySuccess, ErrorSuccess); ////数据源必须按时间顺排序,否则画不出图表 } private void QueryHistorySuccess(GoodsHistoryCycle historyCycle) { if (historyCycle.OhlcDataPoints != null && historyCycle.OhlcDataPoints.Any()) { _iDataPoints = historyCycle.OhlcDataPoints.OrderBy((item) => item.Date).ToList(); } if (_cycleType == CycleType.TimeSharing && historyCycle.OhlcDataPoints.Any() && this._winChart.openCloseArray != null) { _iDataPoints = CalcTimeSpanData(historyCycle); ///补成交前的数据 _iDataPoints = _iDataPoints.OrderBy(item => item.Date).ToList(); RepairChartData(); ///补成交到现在的数据 } if (_iDataPoints != null && _iDataPoints.Any() ) ////分时图没有数据也画 { ReflashChart(); } else { if (_cycleType == CycleType.TimeSharing) ////分时图补数据 { WithoutDataSetLastCose(); ReflashChart(); } } } /// /// 分时图补数据 /// private void WithoutDataSetLastCose() { var date = ApplicationParameter.BasicDateTime.AddMinutes( (int) (ApplicationParameter.ServerTimeNow - ApplicationParameter.BasicDateTime).TotalMinutes); var barDataPoint = new OHLCDataPoints((double) this._currentGoods.LastClose, date.ToOADate()); // var tempdate = DateTime.FromOADate(barDataPoint.Date); UpdateTickChart(barDataPoint); } /// /// 补缺分时图数据 /// /// private List CalcTimeSpanData(GoodsHistoryCycle historyCycle) { ////结算计划是开盘时间[0] 收盘时间[1] DateTime currentTime = DateTime.Now; DateTime.TryParse(ApplicationParameter.ServerTimeNow.ToString("yyyy-MM-dd HH:mm"), out currentTime); var dataPoints = new List(); if (this._winChart.openCloseArray.Any() && this._winChart.openCloseArray[0] < currentTime) //当前时间比开市时间早 { var points = historyCycle.OhlcDataPoints.OrderBy(item => item.Date).ToList(); double currentDate1; DateTime temDate, currentDateTime = this._winChart.openCloseArray[0]; //currentDateTime当前点的时间 double currentValue; //当前值 int currentIndex = 0; var spanList = new List(); //开收市首次开市的时间间隔 for (int j = 0; j < this._winChart.openCloseArray.Length; j++) { var span = Math.Floor((this._winChart.openCloseArray[j] - this._winChart.openCloseArray[0]).TotalMinutes); spanList.Add(span); } for (int i = 0; i < points.Count; i++) { temDate = DateTime.FromOADate(points[i].Date); currentDate1 = Math.Floor((temDate - this._winChart.openCloseArray[0]).TotalMinutes); if (currentDate1 == 0) ////开盘点 { dataPoints.Add(points[i]); #if DEBUG Console.WriteLine("q1:" + temDate.ToString("yyyy-MM-dd HH:mm:ss")); #endif continue; } for (int j = currentIndex; j < spanList.Count - 1; j += 2) { if (spanList[j] > currentDate1) { break; } else if (spanList[j] <= currentDate1 && spanList[j + 1] >= currentDate1) { if (!dataPoints.Any()) { currentDateTime = this._winChart.openCloseArray[0]; currentValue = points[i].Close; } else { currentDateTime = DateTime.FromOADate(dataPoints.Last().Date); if (currentDateTime < this._winChart.openCloseArray[j]) ///第二段时间开始不能使用最后一个为当前时间 { currentDateTime = this._winChart.openCloseArray[j]; } currentValue = dataPoints.Last().Close; } var barSpan = currentDate1 - Math.Floor((currentDateTime - this._winChart.openCloseArray[0]).TotalMinutes) - 1; for (int k = 0; k < barSpan; k++) { var point = new OHLCDataPoints(currentValue, currentDateTime.AddMinutes(k).ToOADate(),0,0); //// 补数据 ////成交量0 #if DEBUG Console.WriteLine("q2:" + currentDateTime.AddMinutes(k).ToString("yyyy-MM-dd HH:mm:ss")); #endif dataPoints.Add(point); } #if DEBUG Console.WriteLine("q3:" + DateTime.FromOADate(points[i].Date).ToString("yyyy-MM-dd HH:mm:ss")); #endif dataPoints.Add(points[i]); currentDateTime = temDate; currentIndex = j; break; } else if (spanList[j + 1] < currentDate1) //开盘第一时间段没有数据 { var curentSpan = Math.Floor((currentDateTime - this._winChart.openCloseArray[0]).TotalMinutes); if (curentSpan < spanList[j + 1]) { var barSpan = spanList[j + 1] - curentSpan; for (int k = 0; k <= barSpan; k++) { var point = new OHLCDataPoints(points[i].Close, currentDateTime.AddMinutes(k).ToOADate(),0,0); //// 补数据 ////成交量0 #if DEBUG Console.WriteLine("q4:" + currentDateTime.AddMinutes(k).ToString("yyyy-MM-dd HH:mm:ss")); #endif dataPoints.Add(point); } currentDateTime = currentDateTime.AddMinutes(barSpan); } currentIndex = j; } } } } return dataPoints; } private void ErrorSuccess(ErrorEntity errorEntity) { //todo:行情请求超时 } /// /// 将源数据转换成数组 /// /// 源数据 /// 返回open, high, low, close, volume, date数据组 private double[][] ConvertData(List source) { var opens = new double[source.Count]; var highs = new double[source.Count]; var lows = new double[source.Count]; var closes = new double[source.Count]; var volumes = new double[source.Count]; var dates = new double[source.Count]; var turnovers = new double[source.Count]; var adjClose = new double[source.Count]; for (int i = 0; i < source.Count; i++) { opens[i] = source[i].Open; highs[i] = source[i].High; lows[i] = source[i].Low; closes[i] = source[i].Close; volumes[i] = source[i].Volume; dates[i] = source[i].Date; adjClose[i] = source[i].Close; turnovers[i] = source[i].TotleTurnovers; } return new double[][] { opens, highs, lows, closes, volumes, dates,adjClose, turnovers }; } /// /// 更新图表周期 /// /// 周期 /// 自定义周期 public void ChangeCycle(CycleType cycleType, TimeSpan timeSpan) { InitBarDataPoints(_currentGoods, cycleType, timeSpan); } /// /// 图表切换商品 /// /// public void ChangeGoods(QuoteGoods goods) { InitBarDataPoints(goods, this._cycleType, this._timeSpan); } /// /// 加载更多数据 /// public void LoadMoreData() { if (_cycleType == CycleType.TimeSharing) return; DateTime endDate = ApplicationParameter.ServerTimeNow; //todo:默认应该是服务端的时间 if (_iDataPoints != null && _iDataPoints.Any()) { endDate = DateTime.FromOADate(_iDataPoints[0].Date); } _quoteDataService.GetHistoryCycleData(_currentGoods, _cycleType,endDate,BasicDateTime, c_DefaultCount, LoadMoreSuccess, ErrorSuccess); } public void LoadMoreSuccess(GoodsHistoryCycle historyCycle) { if (historyCycle != null && historyCycle.OhlcDataPoints != null && historyCycle.OhlcDataPoints.Any()) { historyCycle.OhlcDataPoints = historyCycle.OhlcDataPoints.OrderBy(z => z.Date).ToList(); if (_iDataPoints == null) { _iDataPoints = historyCycle.OhlcDataPoints; } else { _iDataPoints.InsertRange(0, historyCycle.OhlcDataPoints); } if (_iDataPoints != null) { ReflashChart(); } } } /// /// Sets the data source. /// /// The symbol. /// The bar data points. /// Type of the cycle. /// The time span. public void SetDataSource(string symbol, List barDataPoints, CycleType cycleType, TimeSpan timeSpan) { ////数据源必须按时间顺排序,否则画不出图表 _iDataPoints = barDataPoints == null ? null : barDataPoints.OrderBy(z => z.Date).ToList(); CycleType = cycleType; _timeSpan = timeSpan; this._winChart.Symbol = symbol; ReflashChart(); } /// /// 更新Tick数据 /// /// BarPoint public void UpdatePoint(OHLCDataPoints barDataPoint) { #region 设置是否是显示最新数据 var currentTime = DateTime.FromOADate(barDataPoint.Date); ////设置显示结束时间 if (_winChart.Chart != null && _winChart.EndTime != DateTime.MinValue) { var lastIndex = _winChart.Chart.DateToIndex(currentTime); var currentIndex = _winChart.Chart.DateToIndex(_winChart.EndTime); if (Math.Abs(lastIndex - currentIndex) < 5) { _winChart.EndTime = currentTime; } } else { _winChart.EndTime = currentTime; } #endregion UpdateHighLowPrice(barDataPoint.Close); //更新最高最低价 if (_cycleType == CycleType.TimeSharing) { var tempdate = DateTime.FromOADate(barDataPoint.Date); if (IsOnSettlementPlan(tempdate)) { barDataPoint.Date = tempdate.AddSeconds(-tempdate.Date.Second).ToOADate(); UpdateTickChart(barDataPoint); } } else { DateTime updateTime = default(DateTime); if (_iDataPoints == null) { _iDataPoints=new List(); var item = new OHLCDataPoints(barDataPoint.Date, barDataPoint.Open, barDataPoint.High, barDataPoint.Low, barDataPoint.Close, barDataPoint.Volume, barDataPoint.TotleTurnovers); _iDataPoints.Add(item); } else if (IsNotInCycle(DateTime.FromOADate(barDataPoint.Date), ref updateTime)) { var item = new OHLCDataPoints(updateTime.ToOADate(), barDataPoint.Open, barDataPoint.High, barDataPoint.Low, barDataPoint.Close, barDataPoint.Volume, barDataPoint.TotleTurnovers ); _iDataPoints.Add(item); } else { if (_iDataPoints != null && _iDataPoints.Count > 0) { var barPointTmp = _iDataPoints.Last() ; if (barPointTmp == null) return; barPointTmp.Close = barDataPoint.Close; barPointTmp.High = barDataPoint.Close > barPointTmp.High ? barDataPoint.Close : barPointTmp.High; barPointTmp.Low = barDataPoint.Close < barPointTmp.Low ? barDataPoint.Close : barPointTmp.Low; barPointTmp.TotleTurnovers += barDataPoint.TotleTurnovers; barPointTmp.Volume += barDataPoint.Volume; } } } if (_iDataPoints != null) { ReflashChart(); } } #region 分时图 /// /// 更新当前最高,最低价 /// /// private void UpdateHighLowPrice(double currentPrice) { if (_winChart.Chart != null) { if (_winChart.Chart.Highest < currentPrice) { _winChart.Chart.Highest = currentPrice; } else if (_winChart.Chart.Lowsest > currentPrice&¤tPrice!=0) { _winChart.Chart.Lowsest = currentPrice; } } } /// /// 实时行情更新分时数据 /// /// 实时数据 public void UpdateTickChart(OHLCDataPoints barDataPoint) { if (_iDataPoints == null) { _iDataPoints = new List(); } var barPointTmp = _iDataPoints.LastOrDefault(); if (barPointTmp != null) { RepairMinDate(barPointTmp, barDataPoint); } else { if (this._winChart.openCloseArray != null || this._winChart.openCloseArray.Any()) { var ohlc = new OHLCDataPoints(barDataPoint.Close, this._winChart.openCloseArray[0].ToOADate()); //if (! IsOnSettlementPlan(currentMin.Date)) //{ // //todo:当前的时间不在开休市时间内 //} //_iDataPoints.Add(barDataPoint); _iDataPoints.Add(ohlc); RepairMinDate(ohlc, barDataPoint); } } if (_iDataPoints != null) { ReflashChart(); } } /// /// /补分时图数据 /// /// 最近一分钟数据 /// private void RepairMinDate(OHLCDataPoints barPointTmp, OHLCDataPoints barDataPoint) { var spanMinutes = (DateTime.FromOADate(barDataPoint.Date) - DateTime.FromOADate(barPointTmp.Date)).TotalMinutes; var lastdate = DateTime.FromOADate(barPointTmp.Date); if (spanMinutes > 1) { for (int i = 1; i < (int)spanMinutes + 1; i++) //补数据 { if (IsOnSettlementPlan(lastdate.AddMinutes(i))) { var tembarPoint = new OHLCDataPoints(barDataPoint.Close, lastdate.AddMinutes(i).ToOADate(), 0,0); ////补数据成交量为0 _iDataPoints.Add(tembarPoint); } } if (IsOnSettlementPlan(DateTime.FromOADate(barDataPoint.Date))) { _iDataPoints.Add(barDataPoint); } //_iDataPoints.Add(barDataPoint); } else if (spanMinutes > 0) { var current = DateTime.FromOADate(barDataPoint.Date); if (current.Minute == lastdate.Minute) //同分钟 { barPointTmp.Close = barDataPoint.Close; barPointTmp.Volume += barDataPoint.Volume; ////成交量累加 barPointTmp.TotleTurnovers += barDataPoint.TotleTurnovers;////成交额累加 } else { _iDataPoints.Add(barDataPoint); } } } #endregion /// /// 图表切换主题 /// /// The style. public void UpdateSkin(string style) { var skinByName = FormulaSkin.GetSkinByName(style); if (skinByName == null) { return; } _winChart.Skin = style; _winChart.ApplySkin(skinByName); _winChart.CurrentDataCycle = ConvertCycle(_cycleType, _timeSpan); } /// /// 图表放大缩小 /// /// Type of the zoom. public void Zoom(ZoomType zoomType) { var direction = zoomType == ZoomType.In ? 1 : -1; _winChart.ScaleChart(direction * 0.05); } /// /// 是否在周期内 /// public bool IsNotInCycle(DateTime tikTime, ref DateTime CycleDate) { var Rlt = default(bool); if (_iDataPoints != null && _iDataPoints.Any() && tikTime != DateTime.MinValue) { var dt =DateTime.FromOADate( _iDataPoints.Last().Date); var ts = tikTime - dt; switch (_cycleType) { case CycleType.Minutes1: case CycleType.Minutes5: case CycleType.Minutes30: case CycleType.Hour: case CycleType.Hour4: var newDt = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0).AddMinutes(CurrentTimeFrame.TotalMinutes); Rlt = tikTime >= newDt; if (Rlt) { CycleDate = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0).AddMinutes((Math.Floor((ts.TotalMinutes / CurrentTimeFrame.TotalMinutes)) * CurrentTimeFrame.TotalMinutes)); } break; case CycleType.Day: Rlt = tikTime >= new DateTime(dt.Year, dt.Month, dt.Day).AddDays(1); if (Rlt) { CycleDate = new DateTime(dt.Year, dt.Month, dt.Day).AddDays((Math.Floor((ts.TotalDays / CurrentTimeFrame.TotalDays)) * CurrentTimeFrame.TotalDays)); } break; //case CycleType.Week: // Rlt = tikTime >= new DateTime(dt.Year, dt.Month, dt.Day).AddDays((7 - ((int)(DayOfWeek)dt.DayOfWeek))); // if (Rlt) // { // CycleDate = new DateTime(dt.Year, dt.Month, dt.Day).AddDays((Math.Floor((ts.TotalDays / CurrentTimeFrame.TotalDays)) * CurrentTimeFrame.TotalDays)); // } // break; //case CycleType.Month: // Rlt = tikTime >= new DateTime(dt.Year, dt.Month, 1).AddMonths(1); // if (Rlt) // { // CycleDate = new DateTime(dt.Year, tikTime.Month, 1); // } // break; //case CycleType.Quarter: // Rlt = tikTime >= new DateTime(dt.Year, dt.Month, 1).AddMonths(3); // if (Rlt) // { // var mm = (Math.Floor((ts.TotalDays / CurrentTimeFrame.TotalDays)) * CurrentTimeFrame.TotalDays); // CycleDate = new DateTime(dt.Year, dt.Month, 1).AddDays(mm); // } // break; //case CycleType.Year: // Rlt = tikTime >= new DateTime(dt.Year + 1, 1, 1); // if (Rlt) // { // CycleDate = new DateTime(tikTime.Year, 1, 1); // } // break; default: Rlt = false; break; } //Console.WriteLine("time:{0} tikTime:{1} newdate Rlt:{2} RltTime:{3}", dt.ToString(), tikTime.ToString(), newDt.ToString(), Rlt.ToString(), CycleDate.ToString()); } return Rlt; } /// /// 根据周期生成TimeSpan /// public TimeSpan CurrentTimeFrame { get { switch (_cycleType) { case CycleType.Minutes1: return new TimeSpan(0, 1, 0); case CycleType.Minutes5: return new TimeSpan(0, 5, 0); case CycleType.Minutes30: return new TimeSpan(0, 30, 0); case CycleType.Hour: return new TimeSpan(1, 0, 0); case CycleType.Hour4: return new TimeSpan(4, 0, 0); case CycleType.Day: return new TimeSpan(24, 0, 0); default: //分时图为1分 return new TimeSpan(0, 1, 0); } } } /// /// 添加指标 /// /// /// public void AddIndicator(string farmulaName,bool isMain) { if (this._winChart!=null) { if (!isMain) { if (this._winChart.Chart.Areas.Count < c_defaultCount) { this._winChart.InsertDefaultFormula(farmulaName,1); } else { this._winChart.InsertFormulaToArea(this._winChart.Chart.SelectedArea, farmulaName); } } else { this._winChart.InsertFormulaToMain(farmulaName); } } } /// /// 读取数据,周期改变时更新图表(周期,需赋值才能调用) /// private void ReflashChart() { _winChart.DecimalPrice = _currentGoods.GoodsParameters.HqExchFigures; //if (_iDataPoints != null && _iDataPoints.Any()) //{ //} //else //{ //} _winChart.DataManager = this; // _winChart.BindData(); //_winChart.SetQuoteDigits(_currentGoods.GoodsParameters.HqExchFigures); _winChart.NeedRebind(); _winChart.NeedRefresh(); } /// /// 移除选择的指标 /// public void RemoveFormula() { if (this._winChart.Chart.SelectedArea != null && this._winChart.Chart.SelectedArea.SelectedFormula!=null) { this._winChart.Chart.SelectedArea.RemoveFormula(this._winChart.Chart.SelectedArea.SelectedFormula); if (this._winChart.Chart.SelectedArea.Formulas != null && this._winChart.Chart.SelectedArea.Formulas.Count <= 0) { this._winChart.Chart.RemoveArea(this._winChart.Chart.SelectedArea.Name); } ReflashChart(); } } /// /// 是否在结算计划内 /// /// /// private bool IsOnSettlementPlan(DateTime date) { if (this._winChart.openCloseArray == null || !this._winChart.openCloseArray.Any() || this._winChart.openCloseArray.Length % 2 != 0) { return false; } else { for (int i = 0; i < this._winChart.openCloseArray.Length; i += 2) { if (this._winChart.openCloseArray[i] <= date && date <= this._winChart.openCloseArray[i + 1]) { return true; } } return false; } } public new void Dispose() { base.Dispose(); if (_iDataPoints != null) { _iDataPoints.Clear(); } _iDataPoints = null; if (_commonDataProvider != null) { _commonDataProvider.Dispose(); } if (_chartTimer != null) { _chartTimer.Stop(); } } #region 分时图定时器 public CycleType CycleType { get { return _cycleType; } set { _cycleType = value; if (_cycleType == CycleType.TimeSharing) { StartMinituesTimer(); } else { if (_chartTimer != null) { _chartTimer.Stop(); } } } } private bool IsInitTimer = false; private DispatcherTimer _chartTimer; private void StartMinituesTimer() { if (!IsInitTimer) { _chartTimer = new DispatcherTimer(); _chartTimer.Tick+=_chartTimer_Tick; _chartTimer.Interval=new TimeSpan(0,0,30); } _chartTimer.Start(); } private void _chartTimer_Tick(object sender, EventArgs e) { RepairChartData(); } /// /// 补数据 /// private void RepairChartData() { var date = ApplicationParameter.BasicDateTime.AddMinutes( (int)(ApplicationParameter.ServerTimeNow - ApplicationParameter.BasicDateTime).TotalMinutes); var currentPrice = this._currentGoods.CurrentPrice > 0 ? this._currentGoods.CurrentPrice : this._currentGoods.LastClose; var barDataPoint = new OHLCDataPoints((double)currentPrice, date.ToOADate()); UpdateTickChart(barDataPoint); } #endregion #endregion Methods of DataMananer (5) } }