| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264 |
- 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;
- /// <summary>
- /// 标题显示框
- /// </summary>
- private IndicatorLegend legendBtn;
- public Chart Chart
- {
- get { return _chart; }
- set { _chart = value; }
- }
- /// <summary>
- /// 计算公式
- /// </summary>
- public FormulaModel FormulaModel
- {
- get { return _formulaModel; }
- set { _formulaModel = value; }
- }
- /// <summary>
- /// 未计算的数据
- /// </summary>
- public ILineDataSet LineSource
- {
- get { return _lineSource; }
- set { _lineSource = value; }
- }
- /// <summary>
- /// 返回公式计算服务
- /// </summary>
- protected IDataService DataService
- {
- get { return this._dataService; }
- }
- private List<PlotBase> _plotBases;
- /// <summary>
- /// 公式包含的所有线
- /// </summary>
- public List<PlotBase> PlotBases
- {
- get
- {
- return _plotBases;
- }
- set { _plotBases = value; }
- }
- public string Description
- {
- get
- {
- if (this.FormulaModel == null) return string.Empty;
- return this.FormulaModel.FormulaName;
- }
- }
- /// <summary>
- /// 公式所显示的层
- /// </summary>
- public ScaleLayer ScaleLayer
- {
- get { return mScale; }
- set { mScale = value; }
- }
- /// <summary>
- /// 是否是叠加商品
- /// </summary>
- public bool IsComparison { get; set; }
- /// <summary>
- /// 是否显示分时图
- /// </summary>
- public bool IsTimeShare { get; set; }
- /// <summary>
- /// 叠加商品
- /// </summary>
- public GoodsInfo ComparionGoodsInfo { get; set; }
- #region 分时图开收市时间
- /// <summary>
- /// 开市时间
- /// </summary>
- public DateTime OpenTime { get; set; }
- /// <summary>
- /// 收市时间
- /// </summary>
- public DateTime CloseTime { get; set; }
- #endregion
- /// <summary>
- /// 标题显示框
- /// </summary>
- 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<PlotBase>();
- 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<IBarDataPoint>()); //默认不进行计算显示公式有多少个图表
- Calculation(new List<IBarDataPoint>(), 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<IBarDataPoint>().ToList(), chart.CycleType, chart.ChartTimeSpan);
- if (this.FormulaModel.IsMain)
- {
- foreach (var indicatorModel in FormulaModel.IndicatorList) //主图
- {
- indicatorModel.CalculateDataPoints = CalculatetionMainBarSet(indicatorModel).DataPoints;
- }
- }
- }
- /// <summary>
- /// 构建分时图
- /// </summary>
- /// <param name="dataSet">一天内的分钟线历史数据</param>
- /// <param name="chart">图表</param>
- /// <param name="goodsInfo">商品</param>
- public DisplayFormula(ILineDataSet dataSet, Chart chart, GoodsInfo goodsInfo)
- {
- this.FormulaModel = new FormulaModel(c_TimeSharing + goodsInfo.DisplayName);
- this.mLegendBtn = new IndicatorLegend();
- _plotBases = new List<PlotBase>();
- this._chart = chart;
- this.LineSource = dataSet;
- InitTimeShareInfo(this.FormulaModel, dataSet);
- }
- /// <summary>
- /// 初始化分时图数据
- /// </summary>
- /// <param name="formulaModel">公式,分时图中用于显示标题</param>
- private void InitTimeShareInfo(FormulaModel formulaModel, ILineDataSet dataSet)
- {
- if (dataSet==null)
- {
- return;
- }
- formulaModel.IndicatorList = new List<IndicatorModel>();
- //分时图中的价格图
- var indicator = new IndicatorModel(formulaModel)
- {
- LineName = c_TimeSharing_Price,
- LinePlotType = LinePlotType.Line,
- UpBrush = Colors.White,
- LineWidth = 1.2,
- CalculateDataPoints = new List<ILineDataPoint>(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);
- }
- /// <summary>
- /// 更新分时图数据集
- /// </summary>
- /// <param name="dataSet">当前分时图分钟历史数据</param>
- 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<ILineDataPoint>(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;
- }
- }
- /// <summary>
- /// 有实时行情时更新数据
- /// </summary>
- /// <param name="ibarDataPoint">行情数据点</param>
- 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);
- }
- }
- }
- }
- /// <summary>
- /// 更新Tik图表数据
- /// </summary>
- /// <param name="ibarDataPoint">数据点</param>
- 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);
- }
- /// <summary>
- /// 更新叠加分时图商品
- /// </summary>
- /// <param name="ibarDataPoint">行情数据</param>
- 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);
- }
- }
- }
- /// <summary>
- /// 计算平均值
- /// </summary>
- /// <param name="frontPoint">前一个平均值</param>
- /// <param name="currentPoint">当前行情值</param>
- /// <param name="index">数据索引</param>
- /// <returns></returns>
- private ILineDataPoint CaculationAvgPoint(ILineDataPoint frontPoint, IBarDataPoint currentPoint, int index)
- {
- var value = ((index - 1) * frontPoint.Value + currentPoint.Close) / index;
- return new BarDataPoint(currentPoint.Date, value);
- }
- /// <summary>
- ///计算均值
- /// </summary>
- /// <param name="dataSet">数据源</param>
- /// <returns>均值数据</returns>
- private List<ILineDataPoint> GetVolDataPoints(ILineDataSet dataSet)
- {
- var avgDataSet = new List<ILineDataPoint>();
- 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;
- }
- ///// <summary>
- ///// 调用公式计算数据
- ///// </summary>
- ///// <param name="dataPoint">数据源</param>
- //public void Calculation(List<IBarDataPoint> dataPoint)
- //{
- // if (this.FormulaModel == null) return;
- // //计算指标数据
- // _dataService.Calculate(dataPoint, this.FormulaModel, this.Chart.CycleType, this.Chart.ChartTimeSpan);
- //}
- /// <summary>
- /// 调用公式计算数据
- /// </summary>
- /// <param name="dataPoint">数据源</param>
- public void Calculation(List<IBarDataPoint> 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++;
- }
- }
- }
- /// <summary>
- /// 调用公式计算指标
- /// </summary>
- public void Calculation()
- {
- if (_lineSource != null)
- {
- this.Calculation(this._lineSource.DataPoints.OfType<IBarDataPoint>().ToList(), this.Chart.CycleType, this.Chart.ChartTimeSpan);
- }
- }
- #region 设置图表颜色
- /// <summary>
- /// 获取上升颜色
- /// </summary>
- /// <param name="indicator"></param>
- /// <returns></returns>
- 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;
- }
- /// <summary>
- ///获取下降颜色
- /// </summary>
- /// <param name="indicator"></param>
- /// <returns></returns>
- 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;
- }
- /// <summary>
- /// 区域填充颜色
- /// </summary>
- /// <param name="indicator"></param>
- /// <returns></returns>
- 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); //使用从指标菜单添加指标
- }
- }
- /// <summary>
- /// 标题控件
- /// </summary>
- /// <returns></returns>
- public FrameworkElement LegendBtn()
- {
- return this.mLegendBtn;
- }
- /// <summary>
- /// 切换指标
- /// </summary>
- internal void AddIndicators()
- {
- var Formulas = ScaleLayer.AllDisplayFormula;
- var formulaList = new List<string>();
- foreach (var formula in Formulas)
- {
- formulaList.Add(formula.FormulaModel.FormulaName);
- }
- this.DataService.OpenEditor(this._lineSource.DataPoints.OfType<IBarDataPoint>().ToList(), formulaList.ToArray(),
- this.Chart.CycleType, this.Chart.ChartTimeSpan);
- }
- /// <summary>
- /// 第一种图表颜色,显示到标题中
- /// </summary>
- 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<FrameworkElement> AddLegendButton()
- {
- var list = new List<FrameworkElement>();
- this.mLegendBtn.IndicatorLegend_2547(this, this.Chart);
- list.Add(this.mLegendBtn);
- return list;
- }
- /// <summary>
- /// 暂时显示主图
- /// </summary>
- /// <returns></returns>
- 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;
- }
- /// <summary>
- /// 暂时显示成交量
- /// </summary>
- /// <returns></returns>
- 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;
- }
- /// <summary>
- /// 检测画图面板中的图例,并返回它们在aDate日期下的数据面板
- /// </summary>
- /// <param name="aDate">日期</param>
- /// <param name="isDarkBackground"></param>
- /// <param name="isForex"></param>
- /// <returns></returns>
- public List<ControlPair> GetControlPairs(DateTime aDate, bool isDarkBackground, bool isForex)
- {
- var controlPairs = new List<ControlPair>();
- 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;
- }
- /// <summary>
- /// Gets the control pairs.
- /// </summary>
- /// <param name="aDate">A date.</param>
- /// <param name="isDarkBackground">if set to <c>true</c> [is dark background].</param>
- /// <param name="digits">The digits.</param>
- /// <returns>List{ControlPair}.</returns>
- public List<ControlPair> GetControlPairs(DateTime aDate, bool isDarkBackground, int digits)
- {
- var controlPairs = new List<ControlPair>();
- 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;
- }
- ///// <summary>
- ///// 设置新数据
- ///// </summary>
- ///// <param name="aSource"></param>
- //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<IBarDataPoint>().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();
- // }
- //}
- /// <summary>
- /// 设置新数据
- /// </summary>
- /// <param name="aSource">A source.</param>
- /// <param name="refreshFlag">if set to <c>true</c> [refresh flag].</param>
- 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<IBarDataPoint>().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();
- //}));
- }
- }
- /// <summary>
- /// 设置成交量与主图数据。不经编辑器中计算
- /// </summary>
- 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;
- }
- }
- }
- /// <summary>
- /// Gets the size of the chart font.
- /// </summary>
- /// <returns>System.Double.</returns>
- 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);
- }
- }
- /// <summary>
- /// 关闭菜单面板
- /// </summary>
- /// <param name="sender">菜单事件源</param>
- private void ClosePopupMenu(Object sender)
- {
- var popupmenu = GetParent<PopupMenu>(sender as DependencyObject) as PopupMenu;
- if (popupmenu != null)
- {
- popupmenu.ClosePopup();
- }
- }
- /// <summary>
- /// 查询指定类型的父结点
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="dependency"></param>
- /// <returns></returns>
- private DependencyObject GetParent<T>(DependencyObject dependency)
- {
- do
- {
- if (dependency == null) return null;
- if (dependency.GetType() == typeof(T)) return dependency;
- dependency = VisualTreeHelper.GetParent(dependency);
- } while (true);
- }
- /// <summary>
- /// 选择指标
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void SelectFormula(object sender, EventArgs e)
- {
- ClosePopupMenu(sender);
- var chartPanel = ScaleLayer.GetChartPane();
- if (chartPanel == null) return;
- var formulaList = new List<DisplayFormula>();
- 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<IBarDataPoint>().ToList(), formulas,
- this.Chart.CycleType, this.Chart.ChartTimeSpan);
- if (formulaModels == null) return;
- this.ScaleLayer.ClearFormulas();
- this.ScaleLayer.GetChartPane().RemoveAllScaleLayers();
- var formulaDatas = new List<FormulaModel>(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);
- }
- }
- /// <summary>
- /// 创建公式中的图形
- /// </summary>
- public void CreatePlot()
- {
- if (FormulaModel.IndicatorList == null) return;
- var plots = new List<PlotBase>();
- 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); //添加到公式中
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public static List<DisplayFormula> CreateDisplayFormula(ILineDataSet dataSet, Chart chart)
- {
- var dataService = new DataService();
- var formulaModels = dataService.OpenEditor(
- dataSet.DataPoints.OfType<IBarDataPoint>().ToList(), new string[] { },
- chart.CycleType, chart.ChartTimeSpan);
- var formulaDatas = new List<FormulaModel>(formulaModels.Where((formula) => formula.IsMain));
- //不能选择主图
- foreach (var formulaData in formulaDatas)
- {
- formulaModels.Remove(formulaData);
- }
- var list = new List<DisplayFormula>();
- 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;
- }
- /// <summary>
- /// 添加叠加分时图公式
- /// </summary>
- /// <param name="comparisonGoodses">叠加的商品</param>
- /// <param name="chart"></param>
- /// <param name="chartDataSets">叠加商品数据</param>
- /// <returns></returns>
- public static List<DisplayFormula> TimeSharingFormulas(List<ComparisonGoods> comparisonGoodses, Chart chart, Dictionary<string, List<ILineDataPoint>> chartDataSets)
- {
- var comparisonFormulas = new List<DisplayFormula>();
- foreach (var goodsInfo in comparisonGoodses)
- {
- var dataList = chartDataSets.ContainsKey(goodsInfo.GoodsCode)
- ? chartDataSets[goodsInfo.GoodsCode]
- : new List<ILineDataPoint>();
- var displayformula = TimeSharingLineFormula(chart, goodsInfo, dataList);
- comparisonFormulas.Add(displayformula);
- }
- return comparisonFormulas;
- }
- /// <summary>
- /// 创建分时图图表。
- /// </summary>
- /// <param name="chart">图表</param>
- /// <param name="goodsInfo">叠加商品</param>
- /// <param name="dataSetPoint">数据集</param>
- /// <returns></returns>
- public static DisplayFormula TimeSharingLineFormula(Chart chart, GoodsInfo goodsInfo, List<ILineDataPoint> dataSetPoint)
- {
- var formulaModel = new FormulaModel("Main" + goodsInfo.DisplayName);
- var displayformula = new DisplayFormula(formulaModel, chart);
- displayformula.IsComparison = true;
- displayformula.ComparionGoodsInfo = goodsInfo;
- formulaModel.IndicatorList = new List<IndicatorModel>();
- //分时图中的价格图
- 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<ILineDataPoint>();
- }
- formulaModel.IndicatorList.Add(indicator);
- return displayformula;
- }
- /// <summary>
- /// 创建限时图公式
- /// </summary>
- /// <param name="chart">图表控件</param>
- /// <param name="goodsInfo">商品信息</param>
- /// <param name="dataSetPoint">数据点</param>
- /// <returns>限时图公式</returns>
- public static DisplayFormula CreateTikChartFormula(Chart chart, GoodsInfo goodsInfo, List<ILineDataPoint> dataSetPoint)
- {
- var formulaModel = new FormulaModel("即时图" + goodsInfo.DisplayName);
- var displayformula = new DisplayFormula(formulaModel, chart);
- formulaModel.IndicatorList = new List<IndicatorModel>();
- 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<ILineDataPoint>();
- }
- formulaModel.IndicatorList.Add(indicator);
- return displayformula;
- }
- }
- }
|