using MuchInfo.Chart.Data.EnumTypes; using MuchInfo.Chart.Data.Interfaces; using MuchInfo.Chart.Data.Models; using MuchInfo.Chart.DataAdapter; using MuchInfo.Chart.Infrastructure.Data; using MuchInfo.Chart.Infrastructure.Helpers; using MuchInfo.Chart.Infrastructure.Utilities; using MuchInfo.Chart.WPF.Controls.Indicator; using MuchInfo.Chart.WPF.Controls.Utilities; using MuchInfo.Chart.WPF.Helpers; using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; namespace MuchInfo.Chart.WPF.Primitives { public class DisplayFormula { private const string c_TimeSharing = "分时图"; private const string c_TimeSharing_Price = "价格"; private const string c_TimeSharing_AvgPrice = "均价"; private const string c_TimeSharing_Volume = "成交量"; private const string c_TimeSharing_Increase = "涨幅"; private const string c_TimeSharing_IncreaseValue = "涨跌"; private FormulaModel _formulaModel; private IDataService _dataService;//编辑器公式接口 private ILineDataSet _lineSource; private const string c_defualtDownColor = "#FF55FFFF"; private const string c_defualtUpColor = "#FFA43435"; private Chart _chart; protected ScaleLayer mScale; private bool _isDark = true; private static Random _random = new Random(18000); // 没设置颜色时使用随机颜色, private Color[,] BrushArrary; /// /// 标题显示框 /// private IndicatorLegend legendBtn; public Chart Chart { get { return _chart; } set { _chart = value; } } /// /// 计算公式 /// public FormulaModel FormulaModel { get { return _formulaModel; } set { _formulaModel = value; } } /// /// 未计算的数据 /// public ILineDataSet LineSource { get { return _lineSource; } set { _lineSource = value; } } /// /// 返回公式计算服务 /// protected IDataService DataService { get { return this._dataService; } } private List _plotBases; /// /// 公式包含的所有线 /// public List PlotBases { get { return _plotBases; } set { _plotBases = value; } } public string Description { get { if (this.FormulaModel == null) return string.Empty; return this.FormulaModel.FormulaName; } } /// /// 公式所显示的层 /// public ScaleLayer ScaleLayer { get { return mScale; } set { mScale = value; } } /// /// 是否是叠加商品 /// public bool IsComparison { get; set; } /// /// 是否显示分时图 /// public bool IsTimeShare { get; set; } /// /// 叠加商品 /// public GoodsInfo ComparionGoodsInfo { get; set; } #region 分时图开收市时间 /// /// 开市时间 /// public DateTime OpenTime { get; set; } /// /// 收市时间 /// public DateTime CloseTime { get; set; } #endregion /// /// 标题显示框 /// protected virtual IndicatorLegend mLegendBtn { get { return this.legendBtn; } set { var obj = new IndicatorLegend.ClickEventHandler(this.OnIndicatorLegendClick); bool flag = this.legendBtn != null; if (flag) { this.legendBtn.Click -= obj; } this.legendBtn = value; flag = (this.legendBtn != null); if (flag) { this.legendBtn.Click += obj; } } } protected DisplayFormula(FormulaModel formulaModel, Chart chart) { this.FormulaModel = formulaModel; this.mLegendBtn = new IndicatorLegend(); _plotBases = new List(); this._chart = chart; _dataService = new DataService(); } public DisplayFormula(FormulaModel formulaModel, ILineDataSet dataSet, Chart chart) : this(formulaModel, chart) { if (dataSet == null || dataSet.DataPoints == null) { // Calculation(new List()); //默认不进行计算显示公式有多少个图表 Calculation(new List(), chart.CycleType, chart.ChartTimeSpan); } else { // SetSource(dataSet); } _lineSource = dataSet; // CreatePlot(); } public DisplayFormula(FormulaModel formulaModel, ILineDataSet dataSet, Chart chart, GoodsInfo goodsInfo) : this(formulaModel, dataSet, chart) { this.IsComparison = true; ComparionGoodsInfo = goodsInfo; Calculation(this.LineSource.DataPoints.OfType().ToList(), chart.CycleType, chart.ChartTimeSpan); if (this.FormulaModel.IsMain) { foreach (var indicatorModel in FormulaModel.IndicatorList) //主图 { indicatorModel.CalculateDataPoints = CalculatetionMainBarSet(indicatorModel).DataPoints; } } } /// /// 构建分时图 /// /// 一天内的分钟线历史数据 /// 图表 /// 商品 public DisplayFormula(ILineDataSet dataSet, Chart chart, GoodsInfo goodsInfo) { this.FormulaModel = new FormulaModel(c_TimeSharing + goodsInfo.DisplayName); this.mLegendBtn = new IndicatorLegend(); _plotBases = new List(); this._chart = chart; this.LineSource = dataSet; InitTimeShareInfo(this.FormulaModel, dataSet); } /// /// 初始化分时图数据 /// /// 公式,分时图中用于显示标题 private void InitTimeShareInfo(FormulaModel formulaModel, ILineDataSet dataSet) { if (dataSet==null) { return; } formulaModel.IndicatorList = new List(); //分时图中的价格图 var indicator = new IndicatorModel(formulaModel) { LineName = c_TimeSharing_Price, LinePlotType = LinePlotType.Line, UpBrush = Colors.White, LineWidth = 1.2, CalculateDataPoints = new List(dataSet.DataPoints), }; formulaModel.IndicatorList.Add(indicator); //分时图中的均线图 var avgIndicator = new IndicatorModel(formulaModel) { LineName = c_TimeSharing_AvgPrice, LinePlotType = LinePlotType.Line, UpBrush = Colors.Yellow, LineWidth = 1.2, }; avgIndicator.CalculateDataPoints = GetVolDataPoints(dataSet); //计算均值 formulaModel.IndicatorList.Add(avgIndicator); //设置成交量的数据 var volDataSet = new ChartDataSet(); foreach (var dataPoint in dataSet.DataPoints) { var bar = dataPoint as IBarDataPoint; if (bar.Close >= bar.Open) { volDataSet.AddColorDataPoint(bar.Date, bar.Volume, Colors.Yellow, bar.Increase); } else { volDataSet.AddColorDataPoint(bar.Date, bar.Volume, Colors.Yellow, bar.Increase); } } //分时图中的成交量 var volIndicator = new IndicatorModel(formulaModel) { LineName = c_TimeSharing_Volume, LinePlotType = LinePlotType.Bar, UpBrush = Colors.Yellow, VolBar = true, // DownBrush = new SolidColorBrush(Colors.LightGreen), LineWidth = 1.2, CalculateDataPoints = volDataSet.DataPoints, }; formulaModel.IndicatorList.Add(volIndicator); } /// /// 更新分时图数据集 /// /// 当前分时图分钟历史数据 public void UpdateTimeSharingData(ILineDataSet dataSet) { this.LineSource = dataSet; if (FormulaModel == null || FormulaModel.IndicatorList == null || !FormulaModel.IndicatorList.Any()) return; var priceIndcator = FormulaModel.IndicatorList.FirstOrDefault((indicator) => indicator.LineName == c_TimeSharing_Price); var avgIndcator = FormulaModel.IndicatorList.FirstOrDefault((indicator) => indicator.LineName == c_TimeSharing_AvgPrice); var volIndcator = FormulaModel.IndicatorList.FirstOrDefault((indicator) => indicator.LineName == c_TimeSharing_Volume); if (priceIndcator != null && avgIndcator != null && volIndcator != null) { priceIndcator.CalculateDataPoints = new List(dataSet.DataPoints); avgIndcator.CalculateDataPoints = GetVolDataPoints(dataSet); //计算均值 //设置成交量的数据 var volDataSet = new ChartDataSet(); foreach (var dataPoint in dataSet.DataPoints) { var bar = dataPoint as IBarDataPoint; if (bar.Close >= bar.Open) { volDataSet.AddColorDataPoint(bar.Date, bar.Volume, Colors.Yellow, bar.Increase); } else { volDataSet.AddColorDataPoint(bar.Date, bar.Volume, Colors.Yellow, bar.Increase); } } volIndcator.CalculateDataPoints = volDataSet.DataPoints; } } /// /// 有实时行情时更新数据 /// /// 行情数据点 public void UpdatePointSharing(IBarDataPoint ibarDataPoint) { if (this.FormulaModel == null) return; if (FormulaModel.IndicatorList == null || !FormulaModel.IndicatorList.Any()) return; var priceLine = FormulaModel.IndicatorList.FirstOrDefault((indicator) => indicator.LineName == c_TimeSharing_Price); var volBar = FormulaModel.IndicatorList.FirstOrDefault((indicator) => indicator.LineName == c_TimeSharing_Volume); var avgLine = FormulaModel.IndicatorList.FirstOrDefault((indicator) => indicator.LineName == c_TimeSharing_AvgPrice); if (priceLine != null && volBar != null && avgLine != null) { if (priceLine.CalculateDataPoints != null && priceLine.CalculateDataPoints.Any()) { var volData = priceLine.CalculateDataPoints[priceLine.CalculateDataPoints.Count - 1]; var time = ibarDataPoint.Date.AddSeconds(-ibarDataPoint.Date.Second); var timeSpan = time - volData.Date.AddSeconds(-volData.Date.Second); int count = (int)timeSpan.TotalMinutes; if (count == 0) { var curIndex = avgLine.CalculateDataPoints.Count - 1; priceLine.CalculateDataPoints[curIndex] = ibarDataPoint; var colorBar = volBar.CalculateDataPoints[curIndex] as OHLCDataPoint; if (colorBar != null) { colorBar.Value += ibarDataPoint.Volume; } var avgPoint = curIndex == 0 ? ibarDataPoint : CaculationAvgPoint(avgLine.CalculateDataPoints[curIndex - 1], ibarDataPoint, curIndex + 1); avgLine.CalculateDataPoints[curIndex] = avgPoint; } else { if (count >= 2) //使用定时器时更新可能不会出现这情况 { var repairPoint = priceLine.CalculateDataPoints[priceLine.CalculateDataPoints.Count - 1]; var repairBarPoint = repairPoint as IBarDataPoint; if (repairBarPoint != null) { repairBarPoint.Volume = 0; } for (int i = 0; i < count - 1; i++) { priceLine.CalculateDataPoints.Add(repairBarPoint); volBar.CalculateDataPoints.Add( new ColoredDataPoint(ibarDataPoint.Date, 0, 0, 0, 0, Colors.Yellow, 0)); var curIndex = avgLine.CalculateDataPoints.Count - 1; var avgPoint = curIndex == 0 ? ibarDataPoint : CaculationAvgPoint(avgLine.CalculateDataPoints[curIndex - 1], ibarDataPoint, curIndex + 1); avgLine.CalculateDataPoints[curIndex] = avgPoint; } } priceLine.CalculateDataPoints.Add(ibarDataPoint); volBar.CalculateDataPoints.Add( new ColoredDataPoint(ibarDataPoint.Date, ibarDataPoint.Volume, ibarDataPoint.Volume, 0, ibarDataPoint.Volume, Colors.Yellow, 0)); var avgIndex = avgLine.CalculateDataPoints.Count - 1; var avgCurPoint = CaculationAvgPoint(avgLine.CalculateDataPoints[avgIndex - 1], ibarDataPoint, avgIndex + 1); avgLine.CalculateDataPoints.Add(avgCurPoint); } } } } /// /// 更新Tik图表数据 /// /// 数据点 public void UdpdateTickPoint(IBarDataPoint ibarDataPoint) { if (this.FormulaModel == null) return; if (FormulaModel.IndicatorList == null || !FormulaModel.IndicatorList.Any()) return; var dataPoints = FormulaModel.IndicatorList[0]; dataPoints.CalculateDataPoints.Add(ibarDataPoint); } /// /// 更新叠加分时图商品 /// /// 行情数据 public void UpdateComparsionPoint(IBarDataPoint ibarDataPoint) { if (this.FormulaModel == null) return; if (FormulaModel.IndicatorList == null || !FormulaModel.IndicatorList.Any()) return; var priceLine = FormulaModel.IndicatorList[0]; if (priceLine.CalculateDataPoints != null && priceLine.CalculateDataPoints.Any()) { var volData = priceLine.CalculateDataPoints[priceLine.CalculateDataPoints.Count - 1]; var time = ibarDataPoint.Date.AddSeconds(-ibarDataPoint.Date.Second); var timeSpan = time - volData.Date.AddSeconds(-volData.Date.Second); int count = (int)timeSpan.TotalMinutes; if (count == 0) { var curIndex = priceLine.CalculateDataPoints.Count - 1; priceLine.CalculateDataPoints[curIndex] = ibarDataPoint; } else { if (count >= 2) //使用定时器时更新可能不会出现这情况 { var repairPoint = priceLine.CalculateDataPoints[priceLine.CalculateDataPoints.Count - 1]; var repairBarPoint = repairPoint as IBarDataPoint; if (repairBarPoint != null) { repairBarPoint.Volume = 0; } for (int i = 0; i < count - 1; i++) { priceLine.CalculateDataPoints.Add(repairBarPoint); } } priceLine.CalculateDataPoints.Add(ibarDataPoint); } } } /// /// 计算平均值 /// /// 前一个平均值 /// 当前行情值 /// 数据索引 /// private ILineDataPoint CaculationAvgPoint(ILineDataPoint frontPoint, IBarDataPoint currentPoint, int index) { var value = ((index - 1) * frontPoint.Value + currentPoint.Close) / index; return new BarDataPoint(currentPoint.Date, value); } /// ///计算均值 /// /// 数据源 /// 均值数据 private List GetVolDataPoints(ILineDataSet dataSet) { var avgDataSet = new List(); if (dataSet == null || dataSet.DataPoints == null || !dataSet.DataPoints.Any()) return avgDataSet; var ohlcPoint = dataSet.DataPoints[0] as IOHLCDataPoint; if (ohlcPoint == null) return avgDataSet; avgDataSet.Add(new BarDataPoint(ohlcPoint.Date, ohlcPoint.Close)); for (int i = 1; i < dataSet.DataPoints.Count; i++) { var date = dataSet.DataPoints[i].Date; ohlcPoint = dataSet.DataPoints[i] as IOHLCDataPoint; if (ohlcPoint == null) { avgDataSet.Add(new BarDataPoint(date, avgDataSet[i - 1].Value)); } else { var value = (i * avgDataSet[i - 1].Value + ohlcPoint.Close) / (i + 1); avgDataSet.Add(new BarDataPoint(date, value)); } } return avgDataSet; } ///// ///// 调用公式计算数据 ///// ///// 数据源 //public void Calculation(List dataPoint) //{ // if (this.FormulaModel == null) return; // //计算指标数据 // _dataService.Calculate(dataPoint, this.FormulaModel, this.Chart.CycleType, this.Chart.ChartTimeSpan); //} /// /// 调用公式计算数据 /// /// 数据源 public void Calculation(List dataPoint, CycleType cycle, TimeSpan timeSpan) { if (this.FormulaModel == null) return; if (_dataService == null) return; //计算指标数据 _dataService.Calculate(dataPoint, this.FormulaModel, cycle, timeSpan); if (this.FormulaModel.IndicatorList != null && this.FormulaModel.IndicatorList.Any()) { if (BrushArrary == null) { BrushArrary = new Color[FormulaModel.IndicatorList.Count, 3]; } int i = 0; foreach (var indicatorModel in this.FormulaModel.IndicatorList) //指标没有配置颜色的,设置随机颜色 { UpBrush(indicatorModel, i); DownBrush(indicatorModel, i); FillAreaBrush(indicatorModel, i); i++; } } } /// /// 调用公式计算指标 /// public void Calculation() { if (_lineSource != null) { this.Calculation(this._lineSource.DataPoints.OfType().ToList(), this.Chart.CycleType, this.Chart.ChartTimeSpan); } } #region 设置图表颜色 /// /// 获取上升颜色 /// /// /// protected virtual Color UpBrush(IndicatorModel indicator, int i) { if (!ColorHelper.IsEmptyColor(indicator.UpBrush)) return indicator.UpBrush; if ((indicator.ParentFormula.IsMain || indicator.ParentFormula.IsVolume) && this._isDark) { return (Color)ColorConverter.ConvertFromString(c_defualtUpColor); } else if (indicator.ParentFormula.IsMain || indicator.ParentFormula.IsVolume) { return Colors.DarkRed; } else if (indicator.VolBar && ColorHelper.IsEmptyColor(indicator.UpBrush)) { indicator.UpBrush = this._isDark ? (Color)ColorConverter.ConvertFromString(c_defualtUpColor) : Colors.DarkRed; } else if (indicator.PlotNegValsDiffColor && ColorHelper.IsEmptyColor(indicator.UpBrush)) { indicator.UpBrush = this._isDark ? (Color)ColorConverter.ConvertFromString(c_defualtUpColor) : Colors.DarkRed; } else { if (BrushArrary[i, 0] != default(Color)) { indicator.UpBrush = BrushArrary[i, 0]; } else { int count = ColorHelper.AllColors().Count; int index = _random.Next(0, count - 1); indicator.UpBrush = ColorHelper.AllColors()[index].aColor; BrushArrary[i, 0] = ColorHelper.AllColors()[index].aColor; } } return indicator.UpBrush; } /// ///获取下降颜色 /// /// /// private Color DownBrush(IndicatorModel indicator, int i) { if (!ColorHelper.IsEmptyColor(indicator.DownBrush)) return indicator.DownBrush; if ((indicator.ParentFormula.IsMain || indicator.ParentFormula.IsVolume) && this._isDark) { indicator.DownBrush = (Color)ColorConverter.ConvertFromString(c_defualtDownColor); } else if (indicator.ParentFormula.IsMain || indicator.ParentFormula.IsVolume) { indicator.DownBrush = Colors.DarkGreen; } else if (indicator.VolBar && ColorHelper.IsEmptyColor(indicator.DownBrush)) { indicator.DownBrush = this._isDark ? (Color)ColorConverter.ConvertFromString(c_defualtDownColor) : Colors.DarkGreen; } else if (indicator.PlotNegValsDiffColor && ColorHelper.IsEmptyColor(indicator.DownBrush)) { indicator.DownBrush = this._isDark ? (Color)ColorConverter.ConvertFromString(c_defualtDownColor) : Colors.DarkGreen; } else { if (BrushArrary[i, 1] != default(Color)) { indicator.DownBrush = BrushArrary[i, 1]; } else { int count = ColorHelper.AllColors().Count; int index = _random.Next(0, count - 1); indicator.DownBrush = ColorHelper.AllColors()[index].aColor; BrushArrary[i, 1] = ColorHelper.AllColors()[index].aColor; } } return indicator.DownBrush; } /// /// 区域填充颜色 /// /// /// private Color FillAreaBrush(IndicatorModel indicator, int i) { if (!ColorHelper.IsEmptyColor(indicator.AreaBrush)) { return indicator.AreaBrush; } if (BrushArrary[i, 2] != default(Color)) { indicator.AreaBrush = BrushArrary[i, 2]; } else { int count = ColorHelper.AllColors().Count; int index = _random.Next(0, count - 1); indicator.AreaBrush = ColorHelper.AllColors()[index].aColor; BrushArrary[i, 2] = ColorHelper.AllColors()[index].aColor; } return indicator.AreaBrush; } #endregion private void OnIndicatorLegendClick(MouseEventArgs a0) { // this.AddRemoveIndicators((MouseButtonEventArgs)a0); if (this.Chart != null && this.Chart.CycleType != CycleType.TimeSharing) { // AddRemoveIndicators(a0); //使用从指标菜单添加指标 } } /// /// 标题控件 /// /// public FrameworkElement LegendBtn() { return this.mLegendBtn; } /// /// 切换指标 /// internal void AddIndicators() { var Formulas = ScaleLayer.AllDisplayFormula; var formulaList = new List(); foreach (var formula in Formulas) { formulaList.Add(formula.FormulaModel.FormulaName); } this.DataService.OpenEditor(this._lineSource.DataPoints.OfType().ToList(), formulaList.ToArray(), this.Chart.CycleType, this.Chart.ChartTimeSpan); } /// /// 第一种图表颜色,显示到标题中 /// public Color FristPlotBrush() { if (this.FormulaModel != null && this.FormulaModel.IndicatorList != null && this.FormulaModel.IndicatorList.Any()) { var solidBrush = this.FormulaModel.IndicatorList[0].UpBrush; if (solidBrush == null) return Colors.White; return solidBrush; } return Colors.White; } internal virtual List AddLegendButton() { var list = new List(); this.mLegendBtn.IndicatorLegend_2547(this, this.Chart); list.Add(this.mLegendBtn); return list; } /// /// 暂时显示主图 /// /// protected ILineDataSet CalculatetionMainBarSet(IndicatorModel indicator) { var result = new ChartDataSet(); var upColor = !ColorHelper.IsEmptyColor(indicator.UpBrush) ? indicator.UpBrush : Colors.Red; if (ColorHelper.IsEmptyColor(indicator.UpBrush)) { indicator.UpBrush = upColor; } var downColor = !ColorHelper.IsEmptyColor(indicator.DownBrush) ? indicator.DownBrush : Colors.LawnGreen; if (ColorHelper.IsEmptyColor(indicator.DownBrush)) { indicator.DownBrush = downColor; } if (LineSource == null || !LineSource.DataPoints.Any()) return result; foreach (var dataPoint in LineSource.DataPoints) { var bar = dataPoint as IBarDataPoint; if (bar.Close >= bar.Open) { result.AddColoredBarDataPoint(bar.Date, bar.Open, bar.High, bar.Low, bar.Close, bar.Volume, upColor, bar.Turnover, bar.HoldVolume, bar.Increase); } else { result.AddColoredBarDataPoint(bar.Date, bar.Open, bar.High, bar.Low, bar.Close, bar.Volume, downColor, bar.Turnover, bar.HoldVolume, bar.Increase); } } return result; } /// /// 暂时显示成交量 /// /// protected ILineDataSet CalculatetionVolumeBarSet(IndicatorModel indicator) { var result = new ChartDataSet(); var upColor = !ColorHelper.IsEmptyColor(indicator.UpBrush) ? indicator.UpBrush : Colors.Red; if (ColorHelper.IsEmptyColor(indicator.UpBrush)) { indicator.UpBrush = upColor; } var downColor = !ColorHelper.IsEmptyColor(indicator.DownBrush) ? indicator.DownBrush : Colors.LawnGreen; if (ColorHelper.IsEmptyColor(indicator.DownBrush)) { indicator.DownBrush = downColor; } if (this.LineSource == null || LineSource.DataPoints == null || !LineSource.DataPoints.Any()) return result; foreach (var dataPoint in LineSource.DataPoints) { var bar = dataPoint as IBarDataPoint; if (bar.Close >= bar.Open) { result.AddColorDataPoint(bar.Date, bar.Volume, upColor, bar.Increase); } else { result.AddColorDataPoint(bar.Date, bar.Volume, downColor, bar.Increase); } } return result; } /// /// 检测画图面板中的图例,并返回它们在aDate日期下的数据面板 /// /// 日期 /// /// /// public List GetControlPairs(DateTime aDate, bool isDarkBackground, bool isForex) { var controlPairs = new List(); if (!this.IsComparison) { var textBlock3 = new TextBlock { Text = this._formulaModel.FormulaName, Foreground = new SolidColorBrush(FristPlotBrush()), Margin = new Thickness(0.0, 3.0, 0.0, 0.0) }; controlPairs.Add(new ControlPair { ControlLeft = textBlock3 }); } foreach (var plot in PlotBases) { controlPairs.AddRange(plot.GetControlPairs(aDate, isDarkBackground, isForex)); } return controlPairs; } /// /// Gets the control pairs. /// /// A date. /// if set to true [is dark background]. /// The digits. /// List{ControlPair}. public List GetControlPairs(DateTime aDate, bool isDarkBackground, int digits) { var controlPairs = new List(); if (!this.IsComparison) { var textBlock3 = new TextBlock { Text = this._formulaModel.FormulaName, Foreground = new SolidColorBrush(FristPlotBrush()), Margin = new Thickness(0.0, 3.0, 0.0, 0.0) }; controlPairs.Add(new ControlPair { ControlLeft = textBlock3 }); } foreach (var plot in PlotBases) { if ((this.IsTimeShare && !plot.Indicator.VolBar) || this.FormulaModel.IsMain) { controlPairs.AddRange(plot.GetControlPairs(aDate, isDarkBackground, digits)); } else { controlPairs.AddRange(plot.GetControlPairs(aDate, isDarkBackground, 2)); } } return controlPairs; } ///// ///// 设置新数据 ///// ///// //public void SetSource(ILineDataSet aSource) //{ // bool IsUpdate = aSource != null && aSource.Equals(this.LineSource); // this.LineSource = aSource; // if (aSource != null && aSource.DataPoints != null) // { // if (!IsUpdate) // { // Calculation(this.LineSource.DataPoints.OfType().ToList()); //计算 // if (this.FormulaModel.IsMain) // { // foreach (var indicatorModel in FormulaModel.IndicatorList) //主图 // { // indicatorModel.CalculateDataPoints = CalculatetionMainBarSet(indicatorModel).DataPoints; // } // } // else if (this.FormulaModel.IsVolume) //成交量 // { // foreach (var indicatorModel in FormulaModel.IndicatorList) // { // indicatorModel.CalculateDataPoints = CalculatetionVolumeBarSet(indicatorModel).DataPoints; // indicatorModel.LinePlotType = LinePlotType.Bar; // } // } // } // if (this.ScaleLayer == null) return; // CreatePlot(); // } //} /// /// 设置新数据 /// /// A source. /// if set to true [refresh flag]. public void SetSource(ILineDataSet aSource, bool refreshFlag = false) { // if (FormulaModel.IndicatorList == null || !FormulaModel.IndicatorList.Any()) return; this.LineSource = aSource; if (aSource != null && aSource.DataPoints != null) { //if (!IsUpdate) //{ var cycleType = this.Chart.CycleType; var timeSpan = Chart.ChartTimeSpan; //Task.Factory.StartNew(new Action(() => //{ Calculation(this.LineSource.DataPoints.OfType().ToList(), cycleType, timeSpan); //计算 if (this.FormulaModel.IsMain) { foreach (var indicatorModel in FormulaModel.IndicatorList) //主图 { indicatorModel.CalculateDataPoints = CalculatetionMainBarSet(indicatorModel).DataPoints; } } else if (this.FormulaModel.IsVolume) //成交量 { foreach (var indicatorModel in FormulaModel.IndicatorList) { indicatorModel.CalculateDataPoints = CalculatetionVolumeBarSet(indicatorModel).DataPoints; indicatorModel.LinePlotType = LinePlotType.Bar; } } if (this.ScaleLayer == null) return; CreatePlot(); //})); } } /// /// 设置成交量与主图数据。不经编辑器中计算 /// private void SetMainAndVolumeDataSet(FormulaModel formulaModel) { if (formulaModel.IsMain) { foreach (var indicatorModel in formulaModel.IndicatorList) //主图 { indicatorModel.CalculateDataPoints = CalculatetionMainBarSet(indicatorModel).DataPoints; } } else if (formulaModel.IsVolume) //成交量 { foreach (var indicatorModel in formulaModel.IndicatorList) { indicatorModel.CalculateDataPoints = CalculatetionVolumeBarSet(indicatorModel).DataPoints; indicatorModel.LinePlotType = LinePlotType.Bar; } } } /// /// Gets the size of the chart font. /// /// System.Double. public double GetChartFontSize() { return (this.Chart == null) ? 12f : this.Chart.ChartFontSize; } private void AddRemoveIndicators(MouseEventArgs e) { var popUpMenu = new PopupMenu(this.Chart.RootPanel) { FontSize = this.GetChartFontSize() }; popUpMenu.AddItem(LanguageManager.FindResource(LanguageConst.CalculationMenu_Edit), ImageHelper.GetImage("PropertiesHS.png"), new EventHandler(this.ShowEditFormula)); popUpMenu.AddItem(LanguageManager.FindResource(LanguageConst.CalculationMenu_Add), ImageHelper.GetImage("add2.png"), new EventHandler(this.SelectFormula)); popUpMenu.Show(e, new Point(-5.0, -5.0)); e.Handled = true; } //编辑指标 private void ShowEditFormula(object sender, EventArgs e) { ClosePopupMenu(sender); if (this.FormulaModel != null) { _dataService.EditFormula(this.FormulaModel.FormulaName); } } /// /// 关闭菜单面板 /// /// 菜单事件源 private void ClosePopupMenu(Object sender) { var popupmenu = GetParent(sender as DependencyObject) as PopupMenu; if (popupmenu != null) { popupmenu.ClosePopup(); } } /// /// 查询指定类型的父结点 /// /// /// /// private DependencyObject GetParent(DependencyObject dependency) { do { if (dependency == null) return null; if (dependency.GetType() == typeof(T)) return dependency; dependency = VisualTreeHelper.GetParent(dependency); } while (true); } /// /// 选择指标 /// /// /// private void SelectFormula(object sender, EventArgs e) { ClosePopupMenu(sender); var chartPanel = ScaleLayer.GetChartPane(); if (chartPanel == null) return; var formulaList = new List(); foreach (var scaleLayer in chartPanel.AllScaleLayers) { formulaList.AddRange(scaleLayer.AllDisplayFormula); } //不能编辑主图 var mainFormula = formulaList.FirstOrDefault((displayFormula) => displayFormula.FormulaModel != null && displayFormula.FormulaModel.IsMain); formulaList.Remove(mainFormula); string[] formulas = formulaList.Select( (formula) => formula.FormulaModel != null ? formula.FormulaModel.FormulaName : "").ToArray(); if (this.LineSource != null && this.LineSource.DataPoints != null && this.LineSource.DataPoints.Any()) { var formulaModels = _dataService.OpenEditor( this.LineSource.DataPoints.OfType().ToList(), formulas, this.Chart.CycleType, this.Chart.ChartTimeSpan); if (formulaModels == null) return; this.ScaleLayer.ClearFormulas(); this.ScaleLayer.GetChartPane().RemoveAllScaleLayers(); var formulaDatas = new List(formulaModels.Where((formula) => formula.IsMain)); //不能选择主图 foreach (var formulaData in formulaDatas) { formulaModels.Remove(formulaData); } foreach (var formulaModel in formulaModels) { SetMainAndVolumeDataSet(formulaModel); //设置主图与成交量数据 Chart.AddFormula(new DisplayFormula(formulaModel, Chart) { LineSource = this.LineSource, }, false, this.ScaleLayer.GetChartPane()); } Chart.Refresh(true); } } /// /// 创建公式中的图形 /// public void CreatePlot() { if (FormulaModel.IndicatorList == null) return; var plots = new List(); PlotBases.Clear(); if (!IsComparison) { foreach (var indicator in FormulaModel.IndicatorList) { var linePlot = new LinePlot(indicator, this.Chart); // linePlot.InitAsNew(); this.ScaleLayer.AllPlots.Add(linePlot); linePlot.ScaleLayer = this.ScaleLayer; plots.Add(linePlot); } PlotBases.AddRange(plots); //添加到公式中 } else { foreach (var indicator in FormulaModel.IndicatorList) { var comparisonPlot = new ComparisonPlot(indicator, this.Chart, this.ComparionGoodsInfo); this.ScaleLayer.AllPlots.Add(comparisonPlot); comparisonPlot.ScaleLayer = this.ScaleLayer; comparisonPlot.IsActive = true; plots.Add(comparisonPlot); } PlotBases.AddRange(plots); //添加到公式中 } } /// /// /// /// public static List CreateDisplayFormula(ILineDataSet dataSet, Chart chart) { var dataService = new DataService(); var formulaModels = dataService.OpenEditor( dataSet.DataPoints.OfType().ToList(), new string[] { }, chart.CycleType, chart.ChartTimeSpan); var formulaDatas = new List(formulaModels.Where((formula) => formula.IsMain)); //不能选择主图 foreach (var formulaData in formulaDatas) { formulaModels.Remove(formulaData); } var list = new List(); foreach (var formulaModel in formulaModels) { if (formulaModel.IsMain) continue; //不添加主图 if (formulaModel.IsVolume) //成交量数据 { foreach (var indicator in formulaModel.IndicatorList) { var result = new ChartDataSet(); var upColor = !ColorHelper.IsEmptyColor(indicator.UpBrush) ? indicator.UpBrush : Colors.Red; if (ColorHelper.IsEmptyColor(indicator.UpBrush)) { indicator.UpBrush = upColor; } var downColor = !ColorHelper.IsEmptyColor(indicator.DownBrush) ? indicator.DownBrush : Colors.LawnGreen; if (ColorHelper.IsEmptyColor(indicator.DownBrush)) { indicator.DownBrush = downColor; } if (dataSet.DataPoints == null || !dataSet.DataPoints.Any()) break; foreach (var dataPoint in dataSet.DataPoints) { var bar = dataPoint as IBarDataPoint; if (bar.Close >= bar.Open) { result.AddColorDataPoint(bar.Date, bar.Volume, upColor, bar.Increase); } else { result.AddColorDataPoint(bar.Date, bar.Volume, downColor, bar.Increase); } } indicator.CalculateDataPoints = result.DataPoints; } } list.Add(new DisplayFormula(formulaModel, dataSet, chart)); } return list; } /// /// 添加叠加分时图公式 /// /// 叠加的商品 /// /// 叠加商品数据 /// public static List TimeSharingFormulas(List comparisonGoodses, Chart chart, Dictionary> chartDataSets) { var comparisonFormulas = new List(); foreach (var goodsInfo in comparisonGoodses) { var dataList = chartDataSets.ContainsKey(goodsInfo.GoodsCode) ? chartDataSets[goodsInfo.GoodsCode] : new List(); var displayformula = TimeSharingLineFormula(chart, goodsInfo, dataList); comparisonFormulas.Add(displayformula); } return comparisonFormulas; } /// /// 创建分时图图表。 /// /// 图表 /// 叠加商品 /// 数据集 /// public static DisplayFormula TimeSharingLineFormula(Chart chart, GoodsInfo goodsInfo, List dataSetPoint) { var formulaModel = new FormulaModel("Main" + goodsInfo.DisplayName); var displayformula = new DisplayFormula(formulaModel, chart); displayformula.IsComparison = true; displayformula.ComparionGoodsInfo = goodsInfo; formulaModel.IndicatorList = new List(); //分时图中的价格图 var indicator = new IndicatorModel(formulaModel) { LineName = c_TimeSharing_Price, LinePlotType = LinePlotType.Line, //UpBrush = Colors.White, LineWidth = 1.2, }; if (dataSetPoint != null) { indicator.CalculateDataPoints = dataSetPoint; } else { indicator.CalculateDataPoints = new List(); } formulaModel.IndicatorList.Add(indicator); return displayformula; } /// /// 创建限时图公式 /// /// 图表控件 /// 商品信息 /// 数据点 /// 限时图公式 public static DisplayFormula CreateTikChartFormula(Chart chart, GoodsInfo goodsInfo, List dataSetPoint) { var formulaModel = new FormulaModel("即时图" + goodsInfo.DisplayName); var displayformula = new DisplayFormula(formulaModel, chart); formulaModel.IndicatorList = new List(); var indicator = new IndicatorModel(formulaModel) { LineName = c_TimeSharing_Price, LinePlotType = LinePlotType.Line, //UpBrush = Colors.White, LineWidth = 1.2, }; if (dataSetPoint != null) { indicator.CalculateDataPoints = dataSetPoint; } else { indicator.CalculateDataPoints = new List(); } formulaModel.IndicatorList.Add(indicator); return displayformula; } } }