Exemple #1
0
        /// <summary>
        /// Gets the nearest tracker hit.
        /// </summary>
        /// <param name="series">The series.</param>
        /// <param name="point">The point.</param>
        /// <param name="snap">Snap to points.</param>
        /// <param name="pointsOnly">Check points only (no interpolation).</param>
        /// <param name="firesDistance">The distance from the series at which the tracker fires</param>
        /// <param name="checkDistanceBetweenPoints">The value indicating whether to check distance
        /// when showing tracker between data points.</param>
        /// <remarks>
        /// <paramref name="checkDistanceBetweenPoints" /> is ignored if <paramref name="pointsOnly"/> is equal to <c>False</c>.
        /// </remarks>
        /// <returns>A tracker hit result.</returns>
        public static TrackerHitResult GetNearestHit(
            Series.Series series,
            ScreenPoint point,
            bool snap,
            bool pointsOnly,
            double firesDistance,
            bool checkDistanceBetweenPoints)
        {
            if (series == null)
            {
                return(null);
            }

            // Check data points only
            if (snap || pointsOnly)
            {
                var result = series.GetNearestPoint(point, false);
                if (ShouldTrackerOpen(result, point, firesDistance))
                {
                    return(result);
                }
            }

            // Check between data points (if possible)
            if (!pointsOnly)
            {
                var result = series.GetNearestPoint(point, true);
                if (!checkDistanceBetweenPoints || ShouldTrackerOpen(result, point, firesDistance))
                {
                    return(result);
                }
            }

            return(null);
        }
Exemple #2
0
        /// <summary>
        /// Occurs when an input device begins a manipulation on the plot.
        /// </summary>
        /// <param name="e">The <see cref="OxyPlot.OxyMouseEventArgs" /> instance containing the event data.</param>
        public override void Started(OxyMouseEventArgs e)
        {
            base.Started(e);
            this.currentSeries = this.PlotView.ActualModel != null?this.PlotView.ActualModel.GetSeriesFromPoint(e.Position) : null;

            this.Delta(e);
        }
Exemple #3
0
        /// <summary>
        /// Gets the nearest tracker hit.
        /// </summary>
        /// <param name="series">The series.</param>
        /// <param name="point">The point.</param>
        /// <param name="snap">Snap to points.</param>
        /// <param name="pointsOnly">Check points only (no interpolation).</param>
        /// <returns>A tracker hit result.</returns>
        private static TrackerHitResult GetNearestHit(Series.Series series, ScreenPoint point, bool snap, bool pointsOnly)
        {
            if (series == null)
            {
                return(null);
            }

            // Check data points only
            if (snap || pointsOnly)
            {
                var result = series.GetNearestPoint(point, false);
                if (result != null)
                {
                    if (result.Position.DistanceTo(point) < 20)
                    {
                        return(result);
                    }
                }
            }

            // Check between data points (if possible)
            if (!pointsOnly)
            {
                var result = series.GetNearestPoint(point, true);
                return(result);
            }

            return(null);
        }
Exemple #4
0
        /// <summary>
        /// подсчитывает СКО
        /// </summary>
        /// <returns></returns>
        private double GetMathExpected(Series.Series source)
        {
            var deltaCandlesSumm = 0d;

            var start = source.DataCount - period;

            if (start < 1)
            {
                start = 1;
            }
            var count = 0;

            for (var j = start; j < source.DataCount; j++, count++)
            {
                var delta =
                    source is CandlestickSeries
                        ? ((CandlestickSeries)source).Data.Candles[j].close -
                    ((CandlestickSeries)source).Data.Candles[j].open
                        : (((LineSeries)source).GetPrice(j) - ((LineSeries)source).GetPrice(j - 1)) ?? 0;

                deltaCandlesSumm += (delta * delta);
            }


            return(count == 0 ? 0 : Math.Sqrt(deltaCandlesSumm / count));
        }
        /// <summary>
        /// Occurs when an input device begins a manipulation on the plot.
        /// </summary>
        /// <param name="e">The <see cref="OxyPlot.OxyTouchEventArgs" /> instance containing the event data.</param>
        public override void Started(OxyTouchEventArgs e)
        {
            base.Started(e);
            this.currentSeries = this.PlotView.ActualModel != null?this.PlotView.ActualModel.GetSeriesFromPoint(e.Position) : null;

            UpdateTracker(e.Position);
        }
Exemple #6
0
        private float GetPrice(Series.Series source, int i)
        {
            var price =
                source is CandlestickSeries
                    ? ((CandlestickSeries)source).Data.Candles[i].GetPrice(priceType)
                    : series.GetPrice(i) ?? 0;

            return(price);
        }
        private void BuildIndi(Series.Series source)
        {
            if (source is IPriceQuerySeries == false)
            {
                return;
            }

            var curIndex  = 0;
            var prevAccel = 0f;

            for (var j = 0; j < source.DataCount; j++)
            {
                var medianPrice = source is CandlestickSeries
                        ? (((CandlestickSeries)source).Data.Candles[j].high +
                           ((CandlestickSeries)source).Data.Candles[j].low) * 0.5f
                        : (((IPriceQuerySeries)source).GetPrice(j) ?? 0);

                queueFast.Add(medianPrice);
                queueSlow.Add(medianPrice);

                // Если нечего рисовать то пропускаем
                var accelerator = 0f;

                /* А
                 * добил график пустыми столбиками в начале, чтобы крайний столбик был там же, где крайняя свечка
                 */
                if (queueSlow.Length >= periodSlow)
                {
                    var maSlow = queueSlow.Average();
                    var maFast = queueFast.Average();

                    //AO = SMA (MEDIAN PRICE, 5) — SMA (MEDIAN PRICE, 34)
                    var awesome = maFast - maSlow;
                    queueAwesomes.Add(awesome);

                    // Собственно значение ускорения/замедления
                    // AC = AO — SMA (AO, 5)
                    if (queueAwesomes.Length == periodAwesome)
                    {
                        accelerator = awesome - queueAwesomes.Average();
                    }
                }
                //? Класс HistogramBar не описал но вроде он не хитрый и понятно по примеру как его юзать. Для документации достаточно описаь поля и предназначение имхо

                /* А
                 * я чуть иначе раскрасил акселератор, канонически
                 */
                seriesDeltas.data.Add(new HistogramBar
                {
                    color = accelerator >= prevAccel ? ClBarsPositive : ClBarsNegative,
                    index = curIndex++,
                    y     = accelerator
                });
                prevAccel = accelerator;
            }
        }
        /// <summary>
        /// Occurs when a manipulation is complete.
        /// </summary>
        /// <param name="e">The <see cref="OxyPlot.OxyMouseEventArgs" /> instance containing the event data.</param>
        public override void Completed(OxyMouseEventArgs e)
        {
            base.Completed(e);

            this.currentSeries = null;
            this.PlotView.HideTracker();
            if (this.PlotView.ActualModel != null)
            {
                this.PlotView.ActualModel.OnTrackerChanged(null);
            }
        }
Exemple #9
0
        /// <summary>
        /// Occurs when a manipulation is complete.
        /// </summary>
        /// <param name="e">The <see cref="OxyPlot.OxyTouchEventArgs" /> instance containing the event data.</param>
        public override void Completed(OxyTouchEventArgs e)
        {
            base.Completed(e);

            this.currentSeries = null;
            // this.PlotView.HideTracker();
            if (this.PlotView.ActualModel != null)
            {
                this.PlotView.ActualModel.RaiseTrackerChanged(null);
            }
        }
Exemple #10
0
 private float GetPrice(Series.Series source, int i)
 {
     if (source is CandlestickSeries)
     {
         return(((CandlestickSeries)source).Data.Candles[i].GetPrice(priceType));
     }
     if (source is IPriceQuerySeries)
     {
         return(((IPriceQuerySeries)source).GetPrice(i) ?? 0);
     }
     return(0);
 }
Exemple #11
0
        /// <summary>
        /// Occurs when a manipulation is complete.
        /// </summary>
        /// <param name="e">The <see cref="OxyPlot.OxyMouseEventArgs" /> instance containing the event data.</param>
        public override void Completed(OxyMouseEventArgs e)
        {
            base.Completed(e);
            e.Handled = true;

            this.currentSeries = null;
            this.PlotView.HideTracker();
            if (this.PlotView.ActualModel != null)
            {
                this.PlotView.ActualModel.OnTrackerChanged(null);
            }
        }
Exemple #12
0
        /// <summary>
        /// Добавление точек в серии "seriesUp" и "seriesDown" для прорисовки линии
        /// </summary>
        private void MakeRandomWalkLine(Series.Series source)
        {
            if (source is CandlestickSeries == false &&
                source is LineSeries == false)
            {
                return;
            }

            lastCandlestickPrice = source.DataCount > 0
                                       ? (source is CandlestickSeries
                                              ? ((CandlestickSeries)source).Data.Candles[source.DataCount - 1].close
                                              : (((LineSeries)source).GetPrice(source.DataCount - 1) ?? 0))
                                       : 0;

            seriesUp.data.Clear();
            seriesDown.data.Clear();

            var colorIndex = 0;
            var signs      = new Dictionary <int, TrendLineSeries> {
                { 1, seriesUp }, { -1, seriesDown }
            };


            for (var i = 0; i < percentileDeltaValues.GetLength(0); i++) // перебираем все процентили
            {
                var color = clLine[colorIndex++];                        // Задаём цвет
                if (colorIndex >= clLine.Length)
                {
                    colorIndex = 0;
                }

                for (var j = 0; j < percentileDeltaValues.GetLength(1); j++)   // перебираем все дельты на порцентили
                {
                    var x = source.DataCount + j - 1;

                    foreach (var signSeries in signs)
                    {
                        var sign   = signSeries.Key;
                        var series = signSeries.Value;

                        series.data.Add(MakeTrendShelf(x, lastCandlestickPrice + sign * percentileDeltaValues[i, j], color, 1));
                        if (j != 0)
                        {
                            series.data.Add(MakeTrendShelf(x,
                                                           lastCandlestickPrice + sign * percentileDeltaValues[i, j - 1],
                                                           color, dy: sign * percentileDeltaValues[i, j] - sign * percentileDeltaValues[i, j - 1]));
                        }
                    }
                }
            }
        }
Exemple #13
0
        /// <summary>
        /// Расчитываем дисперсию и дельты для каждой процентили.
        /// Если количество свечей не изменяется (а изменяется оно очень редко), то "disper" и "delta" персчитывать не нужно. Они зависят только от
        /// количества свечей.
        /// </summary>
        private void Calculation(Series.Series source)
        {
            var disper = GetMathExpected(source);

            percentileDeltaValues = new double[percentile.Length, forwardSteps];
            for (var i = 0; i < percentile.Length; i++)
            {
                for (var j = 0; j < forwardSteps; j++)
                {
                    percentileDeltaValues[i, j] = QNorm(percentile[i] / 100d, 0, Math.Sqrt(j + 1) * disper, true, false);
                }
            }

            MakeRandomWalkLine(source);
        }
Exemple #14
0
        // ReSharper disable InconsistentNaming
        private void BuildMA(Series.Series source)
        // ReSharper restore InconsistentNaming
        {
            series.Data.Clear();
            float sum      = 0;
            var   frameLen = 0;

            for (var i = 0; i < source.DataCount; i++)
            {
                var price = GetPrice(source, i);

                // простая СС
                if (maType == MovAvgType.Простая)
                {
                    sum += price;
                    if (frameLen < period)
                    {
                        frameLen++;
                    }
                    else
                    {
                        sum -= GetPrice(source, i - period);
                    }
                    series.Data.Add(sum / frameLen);
                    continue;
                }

                // сглаженная СС
                if (smmaPrev.HasValue)
                {
                    var smma = ((period - 1) * smmaPrev.Value + price) / period;
                    series.Data.Add(smma);
                    smmaPrev = smma;
                }
                else
                {
                    queue.Add(price);
                    if (queue.Length == period)
                    {
                        smmaPrev = queue.Average();
                    }
                    series.Data.Add(smmaPrev ?? price);
                }
            }
        }
        private void BuildIndi(Series.Series source)
        {
            if (source is CandlestickSeries == false)
            {
                return;
            }
            var candles = ((CandlestickSeries)source).Data.Candles;

            var currentSign = 0; // текущая операция (покупка/продажа)
            var curIndex    = 0;

            foreach (var candle in candles)
            {
                var price = candle.GetPrice(priceType);
                // обновить средние
                queueFast.Add(price);
                queueSlow.Add(price);

                // посчитать профит
                var delta = 0f;
                if (currentSign != 0)
                {
                    delta = (candle.close - candle.open) * currentSign;
                }
                seriesDeltas.data.Add(new HistogramBar
                {
                    color = delta >= 0 ? ClBarsPositive : ClBarsNegative,
                    index = curIndex++,
                    y     = delta
                });
                // определить знак
                if (queueSlow.Length < periodSlow)
                {
                    continue;
                }
                var maSlow  = queueSlow.Average();
                var maFast  = queueFast.Average();
                var newSign = maFast > maSlow ? 1 : maFast < maSlow ? -1 : 0;
                if (newSign != 0)
                {
                    currentSign = newSign;
                }
            }
        }
Exemple #16
0
        /// <summary>
        /// Occurs when the input device changes position during a manipulation.
        /// </summary>
        /// <param name="e">The <see cref="OxyPlot.OxyMouseEventArgs" /> instance containing the event data.</param>
        public override void Delta(OxyMouseEventArgs e)
        {
            base.Delta(e);
            e.Handled = true;

            if (this.currentSeries == null || !this.LockToInitialSeries)
            {
                // get the nearest
                this.currentSeries = this.PlotView.ActualModel != null?this.PlotView.ActualModel.GetSeriesFromPoint(e.Position, 20) : null;
            }

            if (this.currentSeries == null)
            {
                if (!this.LockToInitialSeries)
                {
                    this.PlotView.HideTracker();
                }

                return;
            }

            var actualModel = this.PlotView.ActualModel;

            if (actualModel == null)
            {
                return;
            }

            if (!actualModel.PlotArea.Contains(e.Position.X, e.Position.Y))
            {
                return;
            }

            var result = GetNearestHit(this.currentSeries, e.Position, this.Snap, this.PointsOnly);

            if (result != null)
            {
                result.PlotModel = this.PlotView.ActualModel;
                this.PlotView.ShowTracker(result);
                this.PlotView.ActualModel.OnTrackerChanged(result);
            }
        }
Exemple #17
0
        /// <summary>
        /// Updates the tracker to the specified position.
        /// </summary>
        /// <param name="position">The position.</param>
        private void UpdateTracker(ScreenPoint position)
        {
            if (this.currentSeries == null || !this.LockToInitialSeries)
            {
                // get the nearest
                this.currentSeries = this.PlotView.ActualModel?.GetSeriesFromPoint(position, this.FiresDistance);
            }

            if (this.currentSeries == null)
            {
                if (!this.LockToInitialSeries)
                {
                    this.PlotView.HideTracker();
                }

                return;
            }

            var actualModel = this.PlotView.ActualModel;

            if (actualModel == null)
            {
                return;
            }

            if (!actualModel.PlotArea.Contains(position.X, position.Y))
            {
                return;
            }

            var result = TrackerHelper.GetNearestHit(
                this.currentSeries, position, this.Snap, this.PointsOnly, this.FiresDistance, this.CheckDistanceBetweenPoints);

            if (result != null)
            {
                result.PlotModel = this.PlotView.ActualModel;
                this.PlotView.ShowTracker(result);
                this.PlotView.ActualModel.RaiseTrackerChanged(result);
            }
        }
        /// <summary>
        /// Occurs when the input device changes position during a manipulation.
        /// </summary>
        /// <param name="e">The <see cref="OxyPlot.OxyMouseEventArgs" /> instance containing the event data.</param>
        public override void Delta(OxyMouseEventArgs e)
        {
            base.Delta(e);

            if (this.currentSeries == null || !this.LockToInitialSeries)
            {
                // get the nearest
                this.currentSeries = this.PlotView.ActualModel != null ? this.PlotView.ActualModel.GetSeriesFromPoint(e.Position, 20) : null;
            }

            if (this.currentSeries == null)
            {
                if (!this.LockToInitialSeries)
                {
                    this.PlotView.HideTracker();
                }

                return;
            }

            var actualModel = this.PlotView.ActualModel;
            if (actualModel == null)
            {
                return;
            }

            if (!actualModel.PlotArea.Contains(e.Position.X, e.Position.Y))
            {
                return;
            }

            var result = GetNearestHit(this.currentSeries, e.Position, this.Snap, this.PointsOnly);
            if (result != null)
            {
                result.PlotModel = this.PlotView.ActualModel;
                this.PlotView.ShowTracker(result);
                this.PlotView.ActualModel.OnTrackerChanged(result);
            }
        }
Exemple #19
0
        /// <summary>
        /// Обновление положения серий "seriesUp" и "seriesDown" (смещение по y).
        /// </summary>
        private void UpdateRandomWalkLine(Series.Series source)
        {
            if (source is CandlestickSeries == false &&
                source is LineSeries == false)
            {
                return;
            }

            if (seriesUp == null)
            {
                return;
            }
            if (seriesUp.data.Count == 0)
            {
                BuildSeries(owner);
                return;
            }

            var newCandlestickPrice = source is CandlestickSeries
                           ? ((CandlestickSeries)source).Data.Candles[source.DataCount - 1].close
                           : (((LineSeries)source).GetPrice(source.DataCount - 1) ?? 0);
            var deltaPrice = newCandlestickPrice - lastCandlestickPrice;

            for (var i = 0; i < seriesUp.data.Count; i++)
            {
                for (var j = 0; j < seriesUp.data[i].linePoints.Count; j++)
                {
                    seriesUp.data[i].linePoints[j] = new PointD(seriesUp.data[i].linePoints[j].X,
                                                                seriesUp.data[i].linePoints[j].Y + deltaPrice);

                    seriesDown.data[i].linePoints[j] = new PointD(seriesDown.data[i].linePoints[j].X,
                                                                  seriesDown.data[i].linePoints[j].Y + deltaPrice);
                }
            }
            lastCandlestickPrice = newCandlestickPrice;
        }
        /// <summary>
        /// Renders the legend for the specified series.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="s">The series.</param>
        /// <param name="rect">The position and size of the legend.</param>
        private void RenderLegend(IRenderContext rc, Series.Series s, OxyRect rect)
        {
            var actualItemAlignment = this.LegendItemAlignment;

            if (this.LegendOrientation == LegendOrientation.Horizontal)
            {
                // center/right alignment is not supported for horizontal orientation
                actualItemAlignment = HorizontalAlignment.Left;
            }

            double x = rect.Left;

            switch (actualItemAlignment)
            {
            case HorizontalAlignment.Center:
                x = (rect.Left + rect.Right) / 2;
                if (this.LegendSymbolPlacement == LegendSymbolPlacement.Left)
                {
                    x -= (this.LegendSymbolLength + this.LegendSymbolMargin) / 2;
                }
                else
                {
                    x -= (this.LegendSymbolLength + this.LegendSymbolMargin) / 2;
                }

                break;

            case HorizontalAlignment.Right:
                x = rect.Right;

                // if (LegendSymbolPlacement == LegendSymbolPlacement.Right)
                x -= this.LegendSymbolLength + this.LegendSymbolMargin;
                break;
            }

            if (this.LegendSymbolPlacement == LegendSymbolPlacement.Left)
            {
                x += this.LegendSymbolLength + this.LegendSymbolMargin;
            }

            double y       = rect.Top;
            var    maxsize = new OxySize(Math.Max(rect.Width - this.LegendSymbolLength - this.LegendSymbolMargin, 0), rect.Height);
            var    actualLegendFontSize = double.IsNaN(this.LegendFontSize) ? this.PlotModel.DefaultFontSize : this.LegendFontSize;
            var    legendTextColor      = s.IsVisible ? this.LegendTextColor : this.SeriesInvisibleTextColor;

            rc.SetToolTip(s.ToolTip);
            var textSize = rc.DrawMathText(
                new ScreenPoint(x, y),
                s.Title,
                legendTextColor.GetActualColor(this.PlotModel.TextColor),
                this.LegendFont ?? this.PlotModel.DefaultFont,
                actualLegendFontSize,
                this.LegendFontWeight,
                0,
                actualItemAlignment,
                VerticalAlignment.Top,
                maxsize,
                true);

            this.SeriesPosMap.Add(s, new OxyRect(new ScreenPoint(x, y), textSize));
            double x0 = x;

            switch (actualItemAlignment)
            {
            case HorizontalAlignment.Center:
                x0 = x - (textSize.Width * 0.5);
                break;

            case HorizontalAlignment.Right:
                x0 = x - textSize.Width;
                break;
            }

            if (s.IsVisible)
            {
                var symbolRect =
                    new OxyRect(
                        this.LegendSymbolPlacement == LegendSymbolPlacement.Right
                            ? x0 + textSize.Width + this.LegendSymbolMargin
                            : x0 - this.LegendSymbolMargin - this.LegendSymbolLength,
                        rect.Top,
                        this.LegendSymbolLength,
                        textSize.Height);

                s.RenderLegend(rc, symbolRect);
            }
            rc.SetToolTip(null);
        }
        /// <summary>
        /// Occurs when an input device begins a manipulation on the plot.
        /// </summary>
        /// <param name="e">The <see cref="OxyPlot.OxyTouchEventArgs" /> instance containing the event data.</param>
        public override void Started(OxyTouchEventArgs e)
        {
            base.Started(e);
            this.currentSeries = this.PlotView.ActualModel != null ? this.PlotView.ActualModel.GetSeriesFromPoint(e.Position) : null;

            UpdateTracker(e.Position);
        }
        private Dictionary <string, double> GetVariableValues(int index, Series.Series seriesSrc,
                                                              int dataCount, List <string> variableNames, string[] tickerNames)
        {
            var varValues = new Dictionary <string, double>();

            if (variableNames == null)
            {
                return(new Dictionary <string, double>());
            }
            // специальные имена переменных:
            // open, low, high, close - текущие OHLC-уровни для свечной серии
            // для серий типа LineSeries доступен только close
            // close#2 - цена два бара назад
            // i - индекс текущей свечи
            // count - количество данных в основном ряду
            // year, month, day, weekday, hour, minute, second
            // eurusd, audjpy#100 - close соотв. валютной пары
            // random - равномерно распред. СЧ на интервале 0..1

            // переменные с неизвестными именами инициализируются нулями
            foreach (var name in variableNames)
            {
                var variableName = name;
                if (name == "i")
                {
                    varValues.Add(name, index);
                    continue;
                }
                if (name == "count")
                {
                    varValues.Add(name, dataCount);
                    continue;
                }

                var tickerName = tickerNames.FirstOrDefault(tn =>
                                                            variableName.StartsWith(tn, StringComparison.OrdinalIgnoreCase));

                if (!string.IsNullOrEmpty(tickerName))
                {// котировка
                    var price = 1.0;
                    if (tickerData.ContainsKey(tickerName))
                    {
                        var tickerQuotes = tickerData[tickerName];
                        if (tickerQuotes.Count > 0)
                        {
                            var datIndex = index - GetDeltaIndexFromSharpSeparatedString(variableName);
                            datIndex = datIndex < 0
                                           ? 0 : datIndex >= tickerQuotes.Count ? tickerQuotes.Count - 1 : datIndex;
                            price = tickerQuotes[datIndex];
                        }
                    }
                    varValues.Add(name, price);
                    continue;
                }
                if (name == "random")
                {
                    varValues.Add(name, randomGener.NextDouble());
                    continue;
                }
                if (name.StartsWith("year") || name.StartsWith("month") ||
                    name.StartsWith("day") || name.StartsWith("weekday") ||
                    name.StartsWith("hour") || name.StartsWith("minute") ||
                    name.StartsWith("second"))
                {
                    // получить дату текущей либо одной из предыдущих точек графика
                    var datIndex = index - GetDeltaIndexFromSharpSeparatedString(name);

                    var curDate = DateTime.Now;
                    if (seriesSrc is StockSeries)
                    {
                        if (datIndex >= 0 && datIndex < ((StockSeries)seriesSrc).Data.Count)
                        {
                            curDate = ((StockSeries)seriesSrc).Data.Candles[datIndex].timeOpen;
                        }
                    }
                    else
                    {
                        if (datIndex >= 0 && datIndex < owner.StockSeries.Data.Count)
                        {
                            curDate = owner.StockSeries.Data.Candles[datIndex].timeOpen;
                        }
                    }

                    if (name.StartsWith("year"))
                    {
                        varValues.Add(name, curDate.Year);
                    }
                    else if (name.StartsWith("month"))
                    {
                        varValues.Add(name, curDate.Month);
                    }
                    else if (name.StartsWith("day"))
                    {
                        varValues.Add(name, curDate.Day);
                    }
                    else if (name.StartsWith("weekday"))
                    {
                        varValues.Add(name, (int)curDate.DayOfWeek);
                    }
                    else if (name.StartsWith("hour"))
                    {
                        varValues.Add(name, curDate.Hour);
                    }
                    else if (name.StartsWith("minute"))
                    {
                        varValues.Add(name, curDate.Minute);
                    }
                    else if (name.StartsWith("second"))
                    {
                        varValues.Add(name, curDate.Second);
                    }

                    continue;
                }
                if (name.StartsWith("close") || name.StartsWith("open") || name.StartsWith("low") || name.StartsWith("high"))
                {// "close", "close#17" ...
                    var datIndex = index - GetDeltaIndexFromSharpSeparatedString(name);
                    // вытащить данные из серии
                    if (seriesSrc is StockSeries)
                    {
                        var candles = ((StockSeries)seriesSrc).Data.Candles;
                        if (datIndex < 0 || datIndex >= candles.Count)
                        {
                            varValues.Add(name, 0);
                            continue;
                        }
                        if (name.StartsWith("open"))
                        {
                            varValues.Add(name, (double)candles[datIndex].open);
                        }
                        else if (name.StartsWith("high"))
                        {
                            varValues.Add(name, (double)candles[datIndex].high);
                        }
                        else if (name.StartsWith("low"))
                        {
                            varValues.Add(name, (double)candles[datIndex].low);
                        }
                        else if (name.StartsWith("close"))
                        {
                            varValues.Add(name, (double)candles[datIndex].close);
                        }
                    }
                    if (seriesSrc is LineSeries)
                    {
                        var serLine = (LineSeries)seriesSrc;
                        if (datIndex < 0 || datIndex >= serLine.Data.Count)
                        {
                            varValues.Add(name, 0);
                            continue;
                        }
                        varValues.Add(name, serLine.Data[datIndex]);
                    }
                    continue;
                }
                if (name.StartsWith("src"))
                {
                    var dotIndex    = name.IndexOf('.');
                    var seriesName  = dotIndex != -1 ? name.Substring(3, dotIndex - 2) : name.Substring(3);
                    var seriesIndex = seriesName.ToInt(0);
                    if (seriesIndex == 0)
                    {
                        varValues.Add(name, 0);
                        continue;
                    }
                    seriesIndex--;
                    if (seriesIndex < 0 || seriesIndex >= SeriesSources.Count)
                    {
                        varValues.Add(name, 0);
                        continue;
                    }
                    var series      = SeriesSources[seriesIndex];
                    var dataIndex   = index - GetDeltaIndexFromSharpSeparatedString(name);
                    var stockSeries = series as StockSeries;
                    if (stockSeries != null)
                    {
                        var candles = stockSeries.Data.Candles;
                        if (dataIndex < 0 || dataIndex >= candles.Count)
                        {
                            varValues.Add(name, 0);
                            continue;
                        }
                        var candleValue = dotIndex != -1 ? name.Substring(dotIndex + 1) : "";
                        if (candleValue == "open")
                        {
                            varValues.Add(name, candles[dataIndex].open);
                        }
                        else if (candleValue == "high")
                        {
                            varValues.Add(name, candles[dataIndex].high);
                        }
                        else if (candleValue == "low")
                        {
                            varValues.Add(name, candles[dataIndex].low);
                        }
                        else // "close" & default
                        {
                            varValues.Add(name, candles[dataIndex].close);
                        }
                        continue;
                    }
                    var lineSeries = series as LineSeries;
                    if (lineSeries != null)
                    {
                        if (dataIndex < 0 || dataIndex >= lineSeries.Data.Count)
                        {
                            varValues.Add(name, 0);
                            continue;
                        }
                        varValues.Add(name, lineSeries.Data[dataIndex]);
                        continue;
                    }
                    varValues.Add(name, 0);
                    continue;
                }
                // переменная не определена вообще - инициализируем 0-м
                varValues.Add(name, 0);
            }
            return(varValues);
        }
        private void BuildSeries(ChartControl chart, bool shouldLoadTickers)
        {
            if (DrawPane != owner.StockPane)
            {
                DrawPane.Title = UniqueName;
            }
            seriesLine.Data.Clear();
            Series.Series seriesSrc = chart.StockSeries;
            var           dataCount = seriesSrc is StockSeries
                                ? ((StockSeries)seriesSrc).Data.Count
                                : seriesSrc is LineSeries
                                      ? ((LineSeries)seriesSrc).Data.Count : 0;
            var varNames = new List <string>();

            foreach (var resv in resolvers)
            {
                if (resv == null)
                {
                    continue;
                }
                var resvVars = resv.GetVariableNames();
                foreach (var varName in resvVars.Where(varName => !varNames.Contains(varName)))
                {
                    varNames.Add(varName);
                }
            }

            randomGener = new Random(DateTime.Now.Millisecond);
            if (shouldLoadTickers)
            {
                LoadTickers(varNames);
            }
            var tickerNames = DalSpot.Instance.GetTickerNames();

            bool hasResolvers = resolvers.Any(resv => resv != null);

            for (var i = 0; i < dataCount; i++)
            {
                if (!hasResolvers)
                {
                    seriesLine.Data.Add(0);
                    continue;
                }
                var values = GetVariableValues(i, seriesSrc, dataCount, varNames, tickerNames);
                // выражение содержит "переменную", которая нигде не определена
                if (values.Count == 0 && varNames.Count > 0)
                {
                    seriesLine.Data.Add(0);
                    continue;
                }
                double totalResult = 0;

                for (var j = 0; j < resolvers.Length; j++)
                {
                    if (resolvers[j] == null)
                    {
                        continue;
                    }

                    double result;
                    if (!resolvers[j].Calculate(values, out result))
                    {
                        result = SubstituteNaN ?? 0;
                    }

                    if (SubstituteNegInfinite.HasValue && double.IsNegativeInfinity(result))
                    {
                        result = SubstituteNegInfinite.Value;
                    }
                    else if (SubstituteInfinite.HasValue && double.IsInfinity(result))
                    {
                        result = SubstituteInfinite.Value;
                    }
                    // обновляем список переменных
                    var resultFuncName = string.Format("fn{0}", j + 1);
                    if (values.ContainsKey(resultFuncName))
                    {
                        values[resultFuncName] = result;
                    }
                    else
                    {
                        values.Add(resultFuncName, result);
                    }
                    // сохраняем последний результат
                    totalResult = result;
                }
                seriesLine.Data.Add(totalResult);
            }
        }
Exemple #24
0
 /// <summary>
 /// Occurs when an input device begins a manipulation on the plot.
 /// </summary>
 /// <param name="e">The <see cref="OxyPlot.OxyMouseEventArgs" /> instance containing the event data.</param>
 public override void Started(OxyMouseEventArgs e)
 {
     base.Started(e);
     this.currentSeries = this.PlotView.ActualModel != null ? this.PlotView.ActualModel.GetSeriesFromPoint(e.Position) : null;
     this.Delta(e);
 }
        /// <summary>
        /// Updates the tracker to the specified position.
        /// </summary>
        /// <param name="position">The position.</param>
        private void UpdateTracker(ScreenPoint position)
        {
            if (this.currentSeries == null || !this.LockToInitialSeries)
            {
                // get the nearest
                this.currentSeries = this.PlotView.ActualModel != null ? this.PlotView.ActualModel.GetSeriesFromPoint(position, 20) : null;
            }

            if (this.currentSeries == null)
            {
                if (!this.LockToInitialSeries)
                {
                    this.PlotView.HideTracker();
                }

                return;
            }

            var actualModel = this.PlotView.ActualModel;
            if (actualModel == null)
            {
                return;
            }

            if (!actualModel.PlotArea.Contains(position.X, position.Y))
            {
                return;
            }

            var result = GetNearestHit(this.currentSeries, position, this.Snap, this.PointsOnly);
            if (result != null)
            {
                result.PlotModel = this.PlotView.ActualModel;
                this.PlotView.ShowTracker(result);
                this.PlotView.ActualModel.RaiseTrackerChanged(result);
            }
        }
Exemple #26
0
        private void BuildBollinger(Series.Series source)
        {
            series.Data.Clear();
            seriesUp.Data.Clear();
            seriesDn.Data.Clear();
            if (source is CandlestickSeries == false &&
                source is LineSeries == false)
            {
                return;
            }

            float sum      = 0;
            var   frameLen = 0;

            for (var i = 0; i < source.DataCount; i++)
            {
                var price = GetPrice(source, i);

                // простая СС
                if (MaType == MovAvgType.Простая)
                {
                    sum += price;
                    if (frameLen < period)
                    {
                        frameLen++;
                    }
                    else
                    {
                        sum -= GetPrice(source, i - period);
                    }
                    series.Data.Add(sum / frameLen);
                }

                // сглаженная СС
                else
                {
                    if (smmaPrev.HasValue)
                    {
                        var smma = ((period - 1) * smmaPrev.Value + price) / period;
                        series.Data.Add(smma);
                        smmaPrev = smma;
                    }
                    else
                    {
                        queue.Add(price);
                        if (queue.Length == period)
                        {
                            smmaPrev = queue.Average();
                        }

                        series.Data.Add(smmaPrev ?? price);
                    }
                }

                // волатильность (СКО)
                // очередь из квадратов отклонений
                var lastMedian = series.Data[series.Data.Count - 1];
                var dev        = lastMedian - price;
                queueDisper.Add((float)(dev * dev));

                var ssd = queueDisper.Length == period
                              ? Math.Sqrt(queueDisper.Average())
                              : 0;

                seriesUp.Data.Add(lastMedian + KVolatile * ssd);
                seriesDn.Data.Add(lastMedian - KVolatile * ssd);
            }
        }