public void BuildSeries(ChartControl chart) { seriesTrendLine.data.Clear(); // актуализировать серии-источники ActualizeSeries(); // по каждой паре серий строить диверы и переводить их Х // координаты в масштаб графика (если ТФ отличаются) var signs = new Dictionary<int, List<DiverMarker>>(); foreach (var src in sets) { if (src.seriesDest == null || src.seriesSrc == null) continue; if (src.seriesDest.isDisposed || src.seriesSrc.isDisposed) continue; if (src.seriesDest is IPriceQuerySeries == false || src.seriesSrc is IPriceQuerySeries == false) continue; BuildDivers(src, signs); } // отобразить foreach (var pair in signs) { var markers = pair.Value; var index = pair.Key; var sign = Math.Sign(markers.Sum(m => m.sign)); if (sign == 0) sign = markers[0].sign; var price = (double)(owner.StockSeries.GetPrice(index) ?? 0); var text = string.Join(", ", markers.Select(m => string.Format("{0}:{1}", m.title, m.sign > 0 ? '^' : 'v'))); var line = new TrendLine { LineStyle = TrendLine.TrendLineStyle.СвечнаяСтрелка, LineColor = sign > 0 ? ColorArrowUp : ColorArrowDown, ShapeAlpha = 192, ShapeFillColor = sign > 0 ? ColorArrowUp : ColorArrowDown, Comment = text }; line.AddPoint(index, price - sign * price * 0.01); line.AddPoint(index, price); seriesTrendLine.data.Add(line); } }
private void TrendLineTypeDialogLoad(object sender, EventArgs e) { // заполнить список линий var w = imageListLarge.ImageSize.Width; var h = imageListLarge.ImageSize.Height; var rectWorld = new RectangleD(0, 0, w, h); var rectCanvas = new Rectangle(0, 0, w, h); var colors = new [] {Color.BlanchedAlmond, Color.GreenYellow, Color.PaleTurquoise}; var colorIndex = 0; foreach (TrendLine.TrendLineStyle lineType in Enum.GetValues(typeof(TrendLine.TrendLineStyle))) { var bmp = new Bitmap(w, h); var line = new TrendLine(); line.AddPoint(h * 0.23, w - 5); line.AddPoint(h * 0.77, 5); if (lineType == TrendLine.TrendLineStyle.Отрезок || lineType == TrendLine.TrendLineStyle.Окружность || lineType == TrendLine.TrendLineStyle.ЛинияСМаркерами || lineType == TrendLine.TrendLineStyle.ОтрезокСМаркерами) { line.linePoints[1] = new PointD(h * 0.32, w - 16); line.linePoints[0] = new PointD(h * 0.68, 16); } line.LineColor = Color.Black; line.ShapeFillColor = colors[colorIndex]; line.LineStyle = lineType; colorIndex++; if (colorIndex == colors.Length) colorIndex = 0; using (var gr = Graphics.FromImage(bmp)) using (var brushes = new BrushesStorage()) using (var pens = new PenStorage()) { gr.SmoothingMode = SmoothingMode.AntiAlias; line.Draw(gr, rectWorld, rectCanvas, pens, brushes); } imageListLarge.Images.Add(bmp); var item = listView.Items.Add(lineType.ToString(), EnumFriendlyName<TrendLine.TrendLineStyle>.GetString(lineType), imageListLarge.Images.Count - 1); item.Tag = lineType; if (lineType == selectedStyle) item.Selected = true; } // привязать картинки к списку listView.LargeImageList = imageListLarge; listView.SmallImageList = imageListLarge; }
//private Rectangle MakeInvalidateArea(TrendLine incompleted, MouseEventArgs e) //{ // var screenA = Chart.Owner.WorldToChartCoords(incompleted.linePoints[0].X, incompleted.linePoints[0].Y); // var screenB = Owner.PointToScreen(new Point(e.X, e.Y)); // screenB = Owner.Owner.PointToScreen(screenB); // var left = Math.Min(screenB.X, screenA.X) - 1; // var top = Math.Min(screenB.Y, screenA.Y) - 1; // var width = Math.Abs(screenB.X - screenA.X) + 2; // var height = Math.Abs(screenB.Y - screenA.Y) + 2; // return new Rectangle(left, top, width, height); //} private void AddSecondPointAuto(TrendLine span) { var x = span.linePoints[0].X; var x1 = x; var y = span.linePoints[0].Y; // определить границы экрана var left = Owner.Owner.StockPane.WorldRect.Left; var right = Owner.Owner.StockPane.WorldRect.Right; var max = Owner.Owner.StockSeries.DataCount; var mid = 0.5*(left + right); var sign = x > mid ? -1 : 1; var lenPix = Owner.Owner.StockPane.CanvasRect.Width/2.2; if (lenPix < 50) lenPix = 50; var sz = Conversion.ScreenToWorld(new SizeD(lenPix, 0), Owner.Owner.StockPane.WorldRect, Owner.Owner.StockPane.CanvasRect); var lenWorld = sz.Width; x += sign*lenWorld; if (x < left) x = left; else if (x > right) x = right; var resultLen = Math.Abs(x - x1); if (resultLen < 1) { span.linePoints[0] = new PointD(0, y); x = max > 0 ? max : 1; } span.AddPoint(x, y); }
public void CopyLine(TrendLine sourceLine) { var newLine = new TrendLine(sourceLine); data.Add(newLine); }
public TrendLine(TrendLine spc) { Name = string.Format("Линия {0}", nextLineNum++); nextPackmanCurrentFrame++; if (nextPackmanCurrentFrame >= packmanFrames.Length) nextPackmanCurrentFrame = 0; packmanCurrentFrame = nextPackmanCurrentFrame; Comment = spc.Comment; lineColor = spc.lineColor; lineStyle = spc.lineStyle; linePoints = spc.linePoints.ToList(); Owner = spc.Owner; penDashStyle = spc.penDashStyle; penWidth = spc.penWidth; pixelScale = spc.pixelScale; selected = spc.selected; shapeAlpha = spc.shapeAlpha; shapeFillColor = spc.shapeFillColor; Comment = spc.Comment; }
protected override void OnMouseDown(List<SeriesEditParameter> parameters, MouseEventArgs e, Keys modifierKeys, out IChartInteractiveObject objectToEdit) { objectToEdit = null; if (e.Button != MouseButtons.Left) return; var pointD = Chart.Owner.MouseToWorldCoords(e.X, e.Y); var incompleted = data.Find(s => s.IsBeingCreated); if (incompleted != null) return; // создать линию, которая будет рисоваться в режиме "резинка" var lineType = SeriesEditParameter.TryGetParamValue(parameters, "Type", TrendLine.TrendLineStyle.Отрезок); var lineColor = SeriesEditParameter.TryGetParamValue(parameters, "Stroke", Color.Black); var fillColor = SeriesEditParameter.TryGetParamValue(parameters, "Filling", Color.White); var alphaColor = SeriesEditParameter.TryGetParamValue(parameters, "Transparency", 192); var isHorisont = SeriesEditParameter.TryGetParamValue(parameters, "Horizontal", false); var isHorisontShift = SeriesEditParameter.TryGetParamValue(parameters, "Horizontal_Shift", true); var showTags = SeriesEditParameter.TryGetParamValue(parameters, "Subtitles", true); var shiftPressed = (Control.ModifierKeys & Keys.Shift) == Keys.Shift; if (!isHorisont) isHorisont = shiftPressed && isHorisontShift; var span = new TrendLine { Owner = this, LineStyle = isHorisont ? TrendLine.TrendLineStyle.Линия : lineType, LineColor = lineColor, ShapeFillColor = fillColor, ShapeAlpha = alphaColor, IsBeingCreated = true, ShowTags = showTags }; span.AddPoint(pointD.X, pointD.Y); if (Owner.Owner.Owner.AdjustObjectColorsOnCreation) span.AjustColorScheme(Owner.Owner.Owner); // автоматом добавить вторую точку на одной высоте if (isHorisont) { var shouldEdit = SeriesEditParameter.TryGetParamValue(parameters, "Edit", true); AddSecondPointAuto(span); if (shouldEdit) objectToEdit = span; } data.Add(span); }
public void OnCandleUpdated(CandleData updatedCandle, List<CandleData> newCandles) { if (alertsList.Count == 0) BuildAlertLevels(updatedCandle.close); if (series.data.Count == 0) { var prices = AlertLevels.ToDecimalArrayUniform(); foreach (var level in prices) { // строим линии var line = new TrendLine { LineStyle = TrendLine.TrendLineStyle.Линия, LineColor = clLine, ShapeAlpha = 192, ShapeFillColor = ClLine }; line.AddPoint(0, (double)level); line.AddPoint(owner.StockSeries.DataCount, (double)level); series.data.Add(line); } } // проверяем срабатывание уровней for (var i = 0; i < alertsList.Count; i++) { if (!alertsList[i].CheckLevel(updatedCandle.close)) continue; try { var wc = new WebClient { Credentials = new NetworkCredential("*****@*****.**", "Br0ker$201!") }; var url = AppConfig.GetStringParam("Publish.Url", "http://forexinvest.ru:8095"); //wc.Credentials = CredentialCache.DefaultCredentials; var serverRequest = WebRequest.Create(url); serverRequest.Credentials = new NetworkCredential("*****@*****.**", "Br0ker$201!"); var serverResponse = serverRequest.GetResponse(); serverResponse.Close(); // отправляем теперь команду на публикацию var msg = HttpUtility.UrlEncode(string.Format("Сработал сигнал по {0}: текущая котировка {1}", owner.Symbol, updatedCandle.close), Encoding.GetEncoding(1251)); var phones = HttpUtility.UrlEncode(SendSmsPhones, Encoding.GetEncoding(1251)); var emails = HttpUtility.UrlEncode(SendEmailList, Encoding.GetEncoding(1251)); var qs = new NameValueCollection { { "command", SendCommandType.Alert.ToString() }, { "msg", msg }, {"sms", SendSmsFlag.ToString()}, { "email", SendEmailFlag.ToString() } , { "phones", phones} , { "emails", emails}}; wc.QueryString = qs; var bret = wc.UploadString(url, "POST", string.Empty); wc.Dispose(); } catch (Exception ex) { Logger.Error("Ошибка отправки алерта на сервер:", ex); } alertsList.RemoveAt(i); AlertLevels = string.Join(" ", alertsList.Select(a => a.Price.ToStringUniform())); i--; } }
private void BuildQuasiExtremums(int srcCount) { double? lastPeak = null; var peakPrice = 0.0; for (var i = 0; i < srcCount; i++) { var index = GetSourcePrice(i, 0); var indexNext = i < srcCount ? GetSourcePrice(i + 1, 0) : index; // если находимся в зоне перекупленности / перепроданности, // если след. точка ниже (выше для перепроданности), // если текущая точка выше последнего максимума (ниже минимума...) var margUp = index >= MargUpper; var margDn = index <= MargLower; if ((margUp && indexNext < index && index > (lastPeak.HasValue ? lastPeak.Value : double.MinValue)) || (margDn && indexNext > index && index < (lastPeak.HasValue ? lastPeak.Value : double.MaxValue))) {// + или - экстремум // нарисовать палочку от peakPrice вверх или вниз var seriesPeakBar = SeriesSources.Count == 2 ? SeriesSources[1] : SeriesSources[0]; if (seriesPeakBar is StockSeries) { var stockSrc = (StockSeries)seriesPeakBar; peakPrice = i < 0 || i >= stockSrc.Data.Count ? 0 : ExtremumDirection == ExtremumBarDirection.СверхуВниз ? (double)stockSrc.Data.Candles[i].low : (double)stockSrc.Data.Candles[i].high; } if (seriesPeakBar is LineSeries) { var lineSrc = (LineSeries)seriesPeakBar; peakPrice = i < 0 || i >= lineSrc.Data.Count ? 0 : lineSrc.Data[i]; } var line = new TrendLine(); line.linePoints.Add(new PointD(i, peakPrice)); line.linePoints.Add(ExtremumDirection == ExtremumBarDirection.СверхуВниз ? new PointD(i, double.MinValue) : new PointD(i, double.MaxValue)); seriesExtr.data.Add(line); // нарисовать столбик от цены вверх или вниз lastPeak = index; continue; } if (!margUp && margDn == false) {// конец отсчета экстремума lastPeak = null; continue; } } }
private void BuildChannel(List<CandleData> candles, int from) { var channel = new Cortege3<PointD, PointD, PointD> { }; var state = ChannelStateInfo.НетКанала; switch (ChannelState) { case ChannelStateInfo.НетКанала: // канала еще нет, ищем сначала по верхним точкам, если не находим, пробуем по нижним найти var channelhigh = GetHighLineChannel(candles, from); var channellow = GetLowLineChannel(candles, from); if ((channelhigh.a == new PointD(0, 0) || channelhigh.b == new PointD(0, 0)) && (channellow.a == new PointD(0, 0) || channellow.b == new PointD(0, 0))) break; if (channelhigh.a == new PointD(0, 0) || channelhigh.b == new PointD(0, 0)) { state = ChannelStateInfo.ПостроенПоМинимумам; channel = channellow; break; } if ((channellow.a == new PointD(0, 0) || channellow.b == new PointD(0, 0))) { state = ChannelStateInfo.ПостроенПоМаксимумам; channel = channelhigh; break; } if (channelhigh.b.X > channellow.b.X || (channelhigh.b.X == channellow.b.X && channelhigh.a.X > channellow.a.X)) { state = ChannelStateInfo.ПостроенПоМаксимумам; channel = channelhigh; break; } state = ChannelStateInfo.ПостроенПоМинимумам; channel = channellow; break; case ChannelStateInfo.ПостроенПоМаксимумам: channel = GetLowLineChannel(candles, from); if (channel.a == new PointD(0, 0) || channel.b == new PointD(0, 0)) return; state = ChannelStateInfo.ПостроенПоМинимумам; break; case ChannelStateInfo.ПостроенПоМинимумам: channel = GetHighLineChannel(candles, from); if (channel.a == new PointD(0, 0) || channel.b == new PointD(0, 0)) return; state = ChannelStateInfo.ПостроенПоМаксимумам; break; } if (lastIndexB == 0 && lastIndexA == 0) { lastIndexA = channel.a.X; lastIndexB = channel.b.X; } if (lastIndexB == channel.b.X && lastIndexA < channel.a.X) { // найденный канал старше текущего, игнорируем return; } if (!ShowAllChannels && lastIndexB > channel.b.X) { // найденный канал уже старый, игнорируем его channel = currChannel; } var a = channel.a; var b = channel.b; var k = (b.Y - a.Y) / (b.X - a.X); // стираем старый канал if (!ShowAllChannels) series.data.Clear(); // находим точку на текущей свече + 1, туда и продлим канал var bx = 0; if (series.data.Count == 0) bx = candles.Count; else bx = (int)b.X + CountAfter + CountForward; if (TradePoints) { // просто покажем точки входа и все // посчитаем точки входа если они есть for (var i = (int)b.X + CountAfter + 1; i < b.X + CountAfter + CountForward; i++) { if (candles.Count <= i) break; var highY = b.Y + k*(i - b.X); var lowY = channel.c.Y + k*(i - channel.c.X); if (highY <= candles[i].high && highY >= candles[i].low) { var detailed = string.Format("S {0}", highY); var tip = new AsteriskTooltip(detailed, detailed) { Price = (float)highY, CandleIndex = i, DateStart = candles[i].timeOpen, Sign = "e", Shape = AsteriskTooltip.ShapeType.СтрелкаВниз, ColorFill = Color.Pink, ColorLine = Color.Black, ColorText = Color.Black }; commentSeries.data.Add(tip); break; } if (lowY >= candles[i].low && lowY <= candles[i].high) { var detailed = string.Format("B {0}", lowY); var tip = new AsteriskTooltip(detailed, detailed) { Price = (float)lowY, CandleIndex = i, DateStart = candles[i].timeOpen, Sign = "e", Shape = AsteriskTooltip.ShapeType.СтрелкаВверх, ColorFill = Color.Green, ColorLine = Color.Black, ColorText = Color.Black }; commentSeries.data.Add(tip); break; } } } else { var line = new TrendLine { LineColor = state == ChannelStateInfo.ПостроенПоМаксимумам ? ClUpLine : ClDownLine, LineStyle = TrendLine.TrendLineStyle.Отрезок }; // линия по двум экстремумам line.linePoints.Add(new PointD(a.X - countBefore, b.Y + k*(a.X - countBefore - b.X))); line.linePoints.Add(new PointD(bx, b.Y + k*(bx - b.X))); series.data.Add(line); line = new TrendLine { LineColor = state == ChannelStateInfo.ПостроенПоМаксимумам ? ClUpLine : ClDownLine, LineStyle = TrendLine.TrendLineStyle.Отрезок }; var c = channel.c; // линия по одному экстремуму line.linePoints.Add(new PointD(a.X - countBefore, c.Y + k*(a.X - countBefore - c.X))); line.linePoints.Add(new PointD(bx, c.Y + k*(bx - c.X))); series.data.Add(line); } ChannelState = state; currChannel = channel; lastIndexA = currChannel.a.X; lastIndexB = currChannel.b.X; }
public void BuildSeries(ChartControl chart) { series.data.Clear(); alertsList.Clear(); BuildAlertLevels(chart.StockSeries.CurrentPriceString.ToFloatUniformSafe()); var prices = AlertLevels.ToDecimalArrayUniform(); foreach (var price in prices) { // строим линии var line = new TrendLine { LineStyle = TrendLine.TrendLineStyle.Линия, LineColor = clLine, ShapeAlpha = 192, ShapeFillColor = ClLine }; line.AddPoint(0, (double)price); line.AddPoint(owner.StockSeries.DataCount, (double)price); series.data.Add(line); } }
private void AddLine(int scaleIndex, int i, double spanPrice) { var line = new TrendLine { LineColor = colors[scaleIndex], LineStyle = TrendLine.TrendLineStyle.Линия, PenDashStyle = styles[scaleIndex], PenWidth = widths[scaleIndex] }; line.AddPoint(i, 0); line.AddPoint(i, spanPrice); series.data.Add(line); }
private void AddRobotHintLineOnChart(RobotHint hint, ChartForm chart) { var pivotIndex = chart.chart.chart.StockSeries.GetIndexByCandleOpen( hint.Time.Value); var line = new TrendLine { Comment = hint.Text, DateStart = hint.Time.Value, LineColor = hint.ColorLine ?? chart.chart.chart.visualSettings.SeriesForeColor, ShapeFillColor = hint.ColorFill ?? chart.chart.chart.visualSettings.SeriesBackColor, LineStyle = TrendLine.TrendLineStyle.Отрезок, Owner = chart.chart.seriesTrendLine }; if (!string.IsNullOrEmpty(hint.HintCode)) line.Name = hint.HintCode; line.AddPoint(pivotIndex, hint.Price.Value); // точку конца отрезка сместить вправо на N свечек line.AddPoint(pivotIndex + 10, hint.Price.Value); chart.chart.seriesTrendLine.data.Add(line); }
/// <summary> /// нарисовать "полочки" уровней SL - TP /// </summary> private void ShowSelectedDealSlTpLines(MarketOrder order) { if (order.StopLoss == null && order.TakeProfit == null) return; var indexStart = (int) owner.StockSeries.GetDoubleIndexByTime(order.TimeEnter); var indexEnd = order.TimeExit.HasValue ? (int) owner.StockSeries.GetDoubleIndexByTime(order.TimeExit.Value) : indexStart; // линия не должна быть слишком короткой var sizePixel = Conversion.WorldToScreen(new SizeD(indexEnd - indexStart, 0), owner.StockPane.WorldRect, owner.StockPane.CanvasRect); const int targetWidth = 35; if (sizePixel.Width < targetWidth) { var newSize = Conversion.ScreenToWorld(new SizeD(targetWidth, 0), owner.StockPane.WorldRect, owner.StockPane.CanvasRect); var len = (int) Math.Round(newSize.Width); indexEnd += len; } var prices = new List<float>(); var tags = new List<string>(); if (order.StopLoss.HasValue) { prices.Add(order.StopLoss.Value); tags.Add("SL"); } if (order.TakeProfit.HasValue) { prices.Add(order.TakeProfit.Value); tags.Add("TP"); } // добавить линии var priceIndex = 0; foreach (var price in prices) { var posLine = new TrendLine { LineColor = owner.StockSeries.DownLineColor, ShapeAlpha = 255, ShapeFillColor = owner.StockSeries.DownLineColor, LineStyle = TrendLine.TrendLineStyle.Отрезок, PenWidth = 1, PenDashStyle = DashStyle.Dot, Name = "drag" }; posLine.AddPoint(indexStart, price); posLine.AddPoint(indexEnd, price); seriesSelectedLines.data.Add(posLine); // добавить с каждой стороны масенький комент: SL или TP var comment = new ChartComment { Text = tags[priceIndex], PivotPrice = price, ArrowAngle = 180, ArrowLength = 2, PivotIndex = indexStart, ColorText = owner.visualSettings.SeriesForeColor, Color = owner.visualSettings.SeriesForeColor, DrawFrame = false, HideBox = true, HideArrow = true, Name = "drag" }; seriesCommentSelected.data.Add(comment); comment = new ChartComment { Text = tags[priceIndex], PivotPrice = price, ArrowAngle = 0, ArrowLength = 2, PivotIndex = indexEnd, ColorText = owner.visualSettings.SeriesForeColor, Color = owner.visualSettings.SeriesForeColor, DrawFrame = false, HideBox = true, HideArrow = true, Name = "drag" }; seriesCommentSelected.data.Add(comment); priceIndex++; } }
private void AddLinePoint(int index, float price) { var line = new TrendLine { LineColor = LineColor, LineStyle = LineStyle }; line.AddPoint(index - 0.4, price); line.AddPoint(index + 0.4, price); mainLine.data.Add(line); }
/// <summary> /// Вспомогательный метод прорисовки отрезка /// </summary> private TrendLine MakeTrendShelf(double x, double y, Color color, double dx = 0, double dy = 0) { var line = new TrendLine { LineStyle = TrendLine.TrendLineStyle.Отрезок, LineColor = color }; line.linePoints.Add(new PointD(x + dx, y + dy)); line.linePoints.Add(new PointD(x, y)); return line; }
private void BuildClassicExtremums(int srcCount) { var seriesPeakBar = SeriesSources.Count == 2 ? SeriesSources[1] : SeriesSources[0]; for (var i = ClassicExtremumBar; i < srcCount - ClassicExtremumBar; i++) { bool isMin = true, isMax = true; var priceExt = GetSourcePrice(i, 0); for (var j = i - ClassicExtremumBar; j <= i + ClassicExtremumBar; j++) { if (j == i) continue; var price = GetSourcePrice(j, 0); if (price > priceExt) isMax = false; if (price < priceExt) isMin = false; if (!isMax && !isMin) break; } if (isMin || isMax) { double peakPrice = 0; if (seriesPeakBar is StockSeries) { var stockSrc = (StockSeries)seriesPeakBar; peakPrice = i < 0 || i >= stockSrc.Data.Count ? 0 : ExtremumDirection == ExtremumBarDirection.СверхуВниз ? (double) stockSrc.Data.Candles[i].low : (double) stockSrc.Data.Candles[i].high; } if (seriesPeakBar is LineSeries) { var lineSrc = (LineSeries)seriesPeakBar; peakPrice = i < 0 || i >= lineSrc.Data.Count ? 0 : lineSrc.Data[i]; } var line = new TrendLine(); line.linePoints.Add(new PointD(i, peakPrice)); line.linePoints.Add(ExtremumDirection == ExtremumBarDirection.СверхуВниз ? new PointD(i, double.MinValue) : new PointD(i, double.MaxValue)); seriesExtr.data.Add(line); } } }
public override IChartInteractiveObject LoadObject(XmlElement objectNode, CandleChartControl owner, bool trimObjectsOutOfHistory = false) { var obj = new TrendLine(); obj.LoadFromXML(objectNode, owner); obj.Owner = this; data.Add(obj); return obj; }
public void BuildSeries(ChartControl chart) { series.data.Clear(); //var candles = chart.StockSeries.Data.Candles; if (SeriesSources[0].GetType() == typeof(CandlestickSeries)) { var candles = ((StockSeries) SeriesSources[0]).Data.Candles; if (candles.Count < period) return; for (var i = period; i < candles.Count; i += period) { var turtle = new TrendLine { LineColor = clLine, ShapeAlpha = 128, ShapeFillColor = Color.Green, LineStyle = Shape == IndicatorShape.Черепаха ? TrendLine.TrendLineStyle.Черепаха : TrendLine.TrendLineStyle.Пэкмен }; turtle.AddPoint(i - period, (double) candles[i - period].open); turtle.AddPoint(i, (double) candles[i].close); series.data.Add(turtle); } } else { if (SeriesSources[0].GetType()== typeof(LineSeries)) { var candles = ((LineSeries)SeriesSources[0]).Data; if (candles.Count < period) return; for (var i = period; i < candles.Count; i += period) { var turtle = new TrendLine { LineColor = clLine, ShapeAlpha = 128, ShapeFillColor = Color.Green, LineStyle = Shape == IndicatorShape.Черепаха ? TrendLine.TrendLineStyle.Черепаха : TrendLine.TrendLineStyle.Пэкмен }; turtle.AddPoint(i - period, (double)candles[i - period]); turtle.AddPoint(i, (double)candles[i]); series.data.Add(turtle); } } } }
private string BuildSeries() { var indi = chart.indicators.FirstOrDefault(i => i.GetType() == typeof (IndicatorExternSeries)); if (indi == null) return "Нет данных для построения (данные из файла)"; var indiData = indi.SeriesResult[0] as CandlestickSeries; if (indiData.DataCount == 0) return "Индикатор пуст"; var candles = chart.chart.StockSeries.Data.Candles; var max = Math.Min(candles.Count, indiData.DataCount); var lastSign = 0; var lastSigns = new RestrictedQueue<int>(skippedCandles); var lines = new List<TrendLine>(); TrendLine trendLine = null; for (var i = 0; i < max; i++) { var candle = indiData.Data[i]; var chartCandle = candles[i]; var thisSign = GetCaymanSign(candle); lastSigns.Add(thisSign); // растянуть регион if (trendLine != null) { trendLine.AddPoint(i, chartCandle.close); if (thisSign == lastSign) continue; } lastSign = thisSign; // завершить регион if (trendLine != null) { trendLine = null; continue; } if (lastSigns.Any(s => s != lastSign) || lastSigns.Length < skippedCandles) continue; // новая линия trendLine = new TrendLine { Comment = CommentSpecName, Magic = LineMagic, LineColor = thisSign > 0 ? colorSell : ColorBuy }; trendLine.AddPoint(i, chartCandle.close); lines.Add(trendLine); } MakeChartGraph(lines); return "Построено " + lines.Count + " областей"; }