예제 #1
0
//grafische Darstellung Einstieg Long
        private void PrepareTradeLong()
        {
            string strArrowUp = "ArrowUp" + Bars.GetTime(CurrentBar);

            DrawArrowUp(strArrowUp, true, Bars.GetTime(Count - 1), Bars.GetOpen(CurrentBar) - 100 * TickSize, Color.Green);
            GapTradeLong = true;
        }
예제 #2
0
//grafische Darstellung Einstieg Short
        private void PrepareTradeShort()
        {
            string strArrowDown = "ArrowDown" + Bars.GetTime(ProcessingBarIndex);

            AddChartArrowDown(strArrowDown, true, Bars.GetTime(Count - 1), Bars.GetOpen(ProcessingBarIndex) + 100 * TickSize, Color.Red);
            GapTradeShort = true;
        }
예제 #3
0
//grafische Darstellung Einstieg Short
        private void PrepareTradeShort()
        {
            string strArrowDown = "ArrowDown" + Bars.GetTime(CurrentBar);

            DrawArrowDown(strArrowDown, true, Bars.GetTime(Count - 1), Bars.GetOpen(CurrentBar) + 100 * TickSize, Color.Red);
            GapTradeShort = true;
        }
예제 #4
0
        /// <summary>
        /// Hold the indicator volume from the underlining indicator
        ///
        /// </summary>

        #region Methods
        public double GetPriceByType(int barNo, PriceSubtype priceType)
        {
            Print(CurrentBar + ":GetPriceByType=" + barNo + "," + priceType);
            double prc = 0;

            switch (priceType)
            {
            case PriceSubtype.Low:
                prc = Bars.GetLow(barNo);
                break;

            case PriceSubtype.High:
                prc = Bars.GetHigh(barNo);
                break;

            case PriceSubtype.Open:
                prc = Bars.GetOpen(barNo);
                break;

            case PriceSubtype.Close:
                prc = Bars.GetClose(barNo);
                break;
            }
            return(prc);
        }
예제 #5
0
//grafische Darstellung Einstieg Long
        private void PrepareTradeLong()
        {
            string strArrowUp = "ArrowUp" + Bars.GetTime(ProcessingBarIndex);

            AddChartArrowUp(strArrowUp, true, Bars.GetTime(Count - 1), Bars.GetOpen(ProcessingBarIndex) - 100 * TickSize, Color.Green);
            GapTradeLong = true;
        }
예제 #6
0
파일: OhlcStyle.cs 프로젝트: theprofe8/nt8
        public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars)
        {
            Bars    bars      = chartBars.Bars;
            float   lineWidth = (float)Math.Max(1, BarWidth);
            Vector2 point0    = new Vector2();
            Vector2 point1    = new Vector2();
            Vector2 point2    = new Vector2();
            Vector2 point3    = new Vector2();
            Vector2 point4    = new Vector2();
            Vector2 point5    = new Vector2();

            for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++)
            {
                SharpDX.Direct2D1.Brush overriddenBrush = chartControl.GetBarOverrideBrush(chartBars, idx);
                double closeValue = bars.GetClose(idx);
                float  close      = chartScale.GetYByValue(closeValue);
                float  high       = chartScale.GetYByValue(bars.GetHigh(idx));
                float  low        = chartScale.GetYByValue(bars.GetLow(idx));
                double openValue  = bars.GetOpen(idx);
                float  open       = chartScale.GetYByValue(openValue);
                float  x          = chartControl.GetXByBarIndex(chartBars, idx);

                point0.X = point1.X = x;
                point0.Y = high - lineWidth * 0.5f;
                point1.Y = low + lineWidth * 0.5f;

                SharpDX.Direct2D1.Brush b = overriddenBrush ?? (closeValue >= openValue ? UpBrushDX : DownBrushDX);

                if (!(b is SharpDX.Direct2D1.SolidColorBrush))
                {
                    TransformBrush(b, new RectangleF(point0.X - lineWidth * 1.5f, point0.Y, lineWidth * 3, point1.Y - point0.Y));
                }

                RenderTarget.DrawLine(point0, point1, b, lineWidth);

                if (!Equals(Mode, OhlcMode.HiLo))
                {
                    point2.X = x + lineWidth * 1.5f;
                    point2.Y = close;
                    point3.X = x;
                    point3.Y = close;

                    RenderTarget.DrawLine(point2, point3, b, lineWidth);

                    if (Equals(Mode, OhlcMode.OHLC))
                    {
                        point4.X = x - lineWidth * 1.5f;
                        point4.Y = open;
                        point5.X = x;
                        point5.Y = open;

                        RenderTarget.DrawLine(point4, point5, b, lineWidth);
                    }
                }
            }
        }
예제 #7
0
        public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars)
        {
            Bars       bars     = chartBars.Bars;
            float      barWidth = GetBarPaintWidth(BarWidthUI);
            RectangleF rect     = new RectangleF();


            for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++)
            {
                Brush  overriddenBrush        = chartControl.GetBarOverrideBrush(chartBars, idx);
                Brush  overriddenOutlineBrush = chartControl.GetCandleOutlineOverrideBrush(chartBars, idx);
                double closeValue             = bars.GetClose(idx);
                float  close     = chartScale.GetYByValue(closeValue);
                double openValue = bars.GetOpen(idx);
                float  open      = chartScale.GetYByValue(openValue);
                float  x         = chartControl.GetXByBarIndex(chartBars, idx);

                Gui.Stroke outlineStroke = closeValue >= openValue ? Stroke              : Stroke2;

                rect.X      = x - barWidth * 0.5f + 0.5f;
                rect.Y      = Math.Min(open, close);
                rect.Width  = barWidth - 1;
                rect.Height = Math.Max(open, close) - Math.Min(open, close);

                Brush b = overriddenBrush ?? (closeValue >= openValue ? UpBrushDX : DownBrushDX);
                if (!(b is SolidColorBrush))
                {
                    TransformBrush(b, rect);
                }
                RenderTarget.FillRectangle(rect, b);

                b = overriddenBrush ?? outlineStroke.BrushDX;
                if (!(b is SolidColorBrush))
                {
                    TransformBrush(b, rect);
                }
                RenderTarget.DrawRectangle(rect, overriddenOutlineBrush ?? outlineStroke.BrushDX, outlineStroke.Width, outlineStroke.StrokeStyle);
            }
        }
        protected override void OnCalculate()
        {
            string strReversalTradeLong  = "ReversalTradeLong" + ProcessingBarIndex;
            string strReversalTradeShort = "ReversalTradeShort" + ProcessingBarIndex;
            string strTradeResultLong;
            string strTradeResultShort;
            Color  colorTextBox;

            // 1 umkehr fallend auf steigend
            //-1 umkehr steigend auf fallend

            if (IsReversalLongTrade() == true)
            {
                ReversalTradeStartTSLong = Bars[0].Time;
                //TargetBarTime = GetTargetBar(Bars[0].Time);
                TargetBarTime = GlobalUtilities.GetTargetBar(Bars, Bars[0].Time, TimeFrame, 1);
                OutSeries.Set(100);
                Reversal2NextBar.Set(100);
            }
            else if (IsReversalShortTrade() == true)
            {
                ReversalTradeStartTSShort = Bars[0].Time;
                //TargetBarTime = GetTargetBar(Bars[0].Time);
                TargetBarTime = GlobalUtilities.GetTargetBar(Bars, Bars[0].Time, TimeFrame, 1);
                OutSeries.Set(-100);
            }
            else
            {
                Reversal2NextBar.Set(0);
            }

            //TradingKerze ist fertig, Zeiteinheit ist abgelaufen
            if (Bars[0].Time == TargetBarTime)
            {
                ReversalTradeResult = (decimal)Bars.GetClose(ProcessingBarIndex) - (decimal)Bars.GetOpen(ProcessingBarIndex);
                TradeCounter       += 1;

                if (ReversalTradeStartTSLong > DateTime.MinValue)
                {
                    ReversalTradeResultTotalLong = ReversalTradeResultTotalLong + ReversalTradeResult;
                    if (ReversalTradeResult < 0)
                    {
                        strTradeResultLong    = "Fail " + ReversalTradeResult.ToString();
                        colorTextBox          = colFail;
                        TradeCounterLongFail += 1;
                    }
                    else
                    {
                        strTradeResultLong   = "Win " + ReversalTradeResult.ToString();
                        colorTextBox         = colWin;
                        TradeCounterLongWin += 1;
                    }
                    AddChartText(strReversalTradeLong, true, strTradeResultLong, Time[1], Bars.GetHigh(ProcessingBarIndex) + (100 * TickSize), 9, Color.Black, new Font("Arial", 9), StringAlignment.Center, Color.Black, colorTextBox, 70);
                }
                else if (ReversalTradeStartTSShort > DateTime.MinValue)
                {
                    ReversalTradeResultTotalShort = ReversalTradeResultTotalShort + ReversalTradeResult;
                    if (ReversalTradeResult < 0)
                    {
                        strTradeResultShort   = "Win " + ReversalTradeResult.ToString();
                        colorTextBox          = colWin;
                        TradeCounterShortWin += 1;
                    }
                    else
                    {
                        strTradeResultShort    = "Fail " + ReversalTradeResult.ToString();
                        colorTextBox           = colFail;
                        TradeCounterShortFail += 1;
                    }
                    AddChartText(strReversalTradeShort, true, strTradeResultShort, Time[1], Bars.GetHigh(ProcessingBarIndex) - (100 * TickSize), 9, Color.Black, new Font("Arial", 9), StringAlignment.Center, Color.Black, colorTextBox, 70);
                }

                //Variablen Resetten
                ReversalTradeStartTSLong  = DateTime.MinValue;
                ReversalTradeStartTSShort = DateTime.MinValue;
            }

            if (IsProcessingBarIndexLast)
            {
                //       Print("LongWin: " + TradeCounterLongWin + " LongFail: " + TradeCounterLongFail + " ShortWin: " + TradeCounterShortWin + " ShortFail: " + TradeCounterShortFail);
                //       Print(Instrument.Name + "Trades: " + TradeCounter + " LongPunkte: " + ReversalTradeResultTotalLong + " ShortPunkte: " + ReversalTradeResultTotalShort);
            }
        }
예제 #9
0
        protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask)
        {
            if (SessionIterator == null)
            {
                SessionIterator = new SessionIterator(bars);
            }

            #region Building Bars from Base Period
            if (bars.Count != tmpCount)             // Reset cache when bars are trimmed
            {
                if (bars.Count == 0)
                {
                    tmpTime      = Core.Globals.MinDate;
                    tmpVolume    = 0;
                    tmpDayCount  = 0;
                    tmpTickCount = 0;
                }
                else
                {
                    tmpTime        = bars.GetTime(bars.Count - 1);
                    tmpVolume      = bars.GetVolume(bars.Count - 1);
                    tmpTickCount   = bars.TickCount;
                    tmpDayCount    = bars.DayCount;
                    bars.LastPrice = bars.GetClose(bars.Count - 1);
                    anchorPrice    = bars.LastPrice;
                }
            }

            bool isNewSession = SessionIterator.IsNewSession(time, isBar);
            bool isCalculateTradingDayDone = false;

            switch (bars.BarsPeriod.BaseBarsPeriodType)
            {
            case BarsPeriodType.Day:
                tmpTime = time.Date;                         // Will be modified for realtime only
                if (!isBar && time >= cacheSessionEnd /* on realtime includesEndTimeStamp is always false */)
                {
                    if (isNewSession)
                    {
                        SessionIterator.GetNextSession(time, isBar);
                        isCalculateTradingDayDone = true;
                    }
                    cacheSessionEnd = SessionIterator.ActualSessionEnd;
                    if (tmpTime < time.Date)
                    {
                        tmpTime = time.Date;                                                  // Make sure timestamps are ascending
                    }
                }

                if (prevTime != tmpTime)
                {
                    tmpDayCount++;
                }

                if (tmpDayCount < bars.BarsPeriod.BaseBarsPeriodValue ||
                    isBar && bars.Count > 0 && tmpTime == bars.LastBarTime.Date ||
                    !isBar && bars.Count > 0 && tmpTime <= bars.LastBarTime.Date)
                {
                    endOfBar = false;
                }
                else
                {
                    prevTime = tmpTime;
                    endOfBar = true;
                }

                break;

            case BarsPeriodType.Minute:

                if (tmpTime == Core.Globals.MinDate)
                {
                    prevTime = tmpTime = TimeToBarTimeMinute(bars, time, isBar);
                }

                if (isBar && time <= tmpTime || !isBar && time < tmpTime)
                {
                    endOfBar = false;
                }
                else
                {
                    prevTime = tmpTime;
                    tmpTime  = TimeToBarTimeMinute(bars, time, isBar);
                    endOfBar = true;
                }
                break;

            case BarsPeriodType.Volume:
                if (tmpTime == Core.Globals.MinDate)
                {
                    tmpVolume = volume;
                    endOfBar  = tmpVolume >= bars.BarsPeriod.BaseBarsPeriodValue;
                    prevTime  = tmpTime = time;
                    if (endOfBar)
                    {
                        tmpVolume = 0;
                    }
                    break;
                }

                tmpVolume += volume;
                endOfBar   = tmpVolume >= bars.BarsPeriod.BaseBarsPeriodValue;
                if (endOfBar)
                {
                    prevTime  = tmpTime;
                    tmpVolume = 0;
                }
                tmpTime = time;
                break;

            case BarsPeriodType.Tick:
                if (tmpTime == Core.Globals.MinDate || bars.BarsPeriod.BaseBarsPeriodValue == 1)
                {
                    prevTime     = tmpTime == Core.Globals.MinDate ? time : tmpTime;
                    tmpTime      = time;
                    tmpTickCount = bars.BarsPeriod.BaseBarsPeriodValue == 1 ? 0 : 1;
                    endOfBar     = bars.BarsPeriod.BaseBarsPeriodValue == 1;
                    break;
                }

                if (tmpTickCount < bars.BarsPeriod.BaseBarsPeriodValue)
                {
                    tmpTime  = time;
                    endOfBar = false;
                    tmpTickCount++;
                }
                else
                {
                    prevTime     = tmpTime;
                    tmpTime      = time;
                    endOfBar     = true;
                    tmpTickCount = 1;
                }
                break;

            case BarsPeriodType.Month:
                if (tmpTime == Core.Globals.MinDate)
                {
                    prevTime = tmpTime = TimeToBarTimeMonth(time, bars.BarsPeriod.BaseBarsPeriodValue);
                }

                if (time.Month <= tmpTime.Month && time.Year == tmpTime.Year || time.Year < tmpTime.Year)
                {
                    endOfBar = false;
                }
                else
                {
                    prevTime = tmpTime;
                    endOfBar = true;
                    tmpTime  = TimeToBarTimeMonth(time, bars.BarsPeriod.BaseBarsPeriodValue);
                }
                break;

            case BarsPeriodType.Second:
                if (tmpTime == Core.Globals.MinDate)
                {
                    prevTime = tmpTime = TimeToBarTimeSecond(bars, time, isBar);
                }
                if (bars.BarsPeriod.BaseBarsPeriodValue > 1 && time < tmpTime || bars.BarsPeriod.BaseBarsPeriodValue == 1 && time <= tmpTime)
                {
                    endOfBar = false;
                }
                else
                {
                    prevTime = tmpTime;
                    tmpTime  = TimeToBarTimeSecond(bars, time, isBar);
                    endOfBar = true;
                }
                break;

            case BarsPeriodType.Week:
                if (tmpTime == Core.Globals.MinDate)
                {
                    prevTime = tmpTime = TimeToBarTimeWeek(time.Date, tmpTime.Date, bars.BarsPeriod.BaseBarsPeriodValue);
                }
                if (time.Date <= tmpTime.Date)
                {
                    endOfBar = false;
                }
                else
                {
                    prevTime = tmpTime;
                    endOfBar = true;
                    tmpTime  = TimeToBarTimeWeek(time.Date, tmpTime.Date, bars.BarsPeriod.BaseBarsPeriodValue);
                }
                break;

            case BarsPeriodType.Year:
                if (tmpTime == Core.Globals.MinDate)
                {
                    prevTime = tmpTime = TimeToBarTimeYear(time, bars.BarsPeriod.Value);
                }
                if (time.Year <= tmpTime.Year)
                {
                    endOfBar = false;
                }
                else
                {
                    prevTime = tmpTime;
                    endOfBar = true;
                    tmpTime  = TimeToBarTimeYear(time, bars.BarsPeriod.Value);
                }
                break;
            }
            #endregion
            #region Kagi Logic

            reversalPoint = bars.BarsPeriod.ReversalType == ReversalType.Tick ? bars.BarsPeriod.Value * bars.Instrument.MasterInstrument.TickSize : bars.BarsPeriod.Value / 100.0 * anchorPrice;

            if (bars.Count == 0 || IsIntraday && (bars.BarsPeriod.BaseBarsPeriodType != BarsPeriodType.Second && bars.IsResetOnNewTradingDay && isNewSession ||
                                                  bars.BarsPeriod.BaseBarsPeriodType == BarsPeriodType.Second && bars.IsResetOnNewTradingDay && isNewSession))
            {
                if (isNewSession && !isCalculateTradingDayDone)
                {
                    SessionIterator.GetNextSession(tmpTime, isBar);
                }

                if (bars.Count > 0)
                {
                    double lastOpen  = bars.GetOpen(bars.Count - 1);
                    double lastHigh  = bars.GetHigh(bars.Count - 1);
                    double lastLow   = bars.GetLow(bars.Count - 1);
                    double lastClose = bars.GetClose(bars.Count - 1);

                    if (bars.Count == tmpCount)
                    {
                        CalculateKagiBar(bars, lastOpen, lastHigh, lastLow, lastClose, prevTime, volume);
                    }
                }

                AddBar(bars, close, close, close, close, tmpTime, volume);
                anchorPrice    = close;
                trend          = Trend.Undetermined;
                prevTime       = tmpTime;
                volumeCount    = 0;
                bars.LastPrice = close;
                tmpCount       = bars.Count;
                return;
            }

            double c = bars.GetClose(bars.Count - 1);
            double o = bars.GetOpen(bars.Count - 1);
            double h = bars.GetHigh(bars.Count - 1);
            double l = bars.GetLow(bars.Count - 1);

            if (endOfBar)
            {
                CalculateKagiBar(bars, o, h, l, c, prevTime, volume);
            }
            else
            {
                volumeCount += volume;
            }

            bars.LastPrice = close;
            tmpCount       = bars.Count;
            #endregion
        }
예제 #10
0
		/// <summary>
		/// </summary>
		/// <param name="bars"></param>
		/// <param name="open"></param>
		/// <param name="high"></param>
		/// <param name="low"></param>
		/// <param name="close"></param>
		/// <param name="time"></param>
		/// <param name="volume"></param>
		/// <param name="isRealtime"></param>
		public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime)
		{
			#region Building Bars from Base Period
			if (bars.Count != tmpCount) // reset cache when bars are trimmed
				if (bars.Count == 0)
				{
					tmpTime			= Cbi.Globals.MinDate;
					tmpVolume		= 0;
					tmpDayCount		= 0;
					tmpTickCount	= 0;
				}
				else
				{
					tmpTime			= bars.GetTime(bars.Count - 1);
					tmpVolume		= bars.GetVolume(bars.Count - 1);
					tmpTickCount	= bars.TickCount;
					tmpDayCount		= bars.DayCount;
					bars.LastPrice	= bars.GetClose(bars.Count - 1);
					anchorPrice		= bars.LastPrice;
				}

			switch (bars.Period.BasePeriodType)
			{
				case PeriodType.Day:
					tmpTime = time.Date; // will be modified for realtime only
					if (isRealtime && time >= cacheSessionEnd /* on realtime include60 is always false */)
					{
						bars.Session.GetSessionDate(time, false, out tmpTime, out cacheSessionEnd);
						if (tmpTime < time.Date) tmpTime = time.Date; // make sure timestamps are ascending
					}

					if (prevTime != tmpTime) tmpDayCount++;

					if (tmpDayCount < bars.Period.BasePeriodValue
						|| (!isRealtime && bars.Count > 0 && tmpTime == bars.TimeLastBar.Date)
						|| (isRealtime && bars.Count > 0 && tmpTime <= bars.TimeLastBar.Date))
						endOfBar = false;
					else
					{
						prevTime = tmpTime;
						endOfBar = true;
					}

					break;

				case PeriodType.Minute:

					if (tmpTime == Cbi.Globals.MinDate)
						prevTime = tmpTime = TimeToBarTimeMinute(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue, isRealtime);

					if (!isRealtime && time <= tmpTime || isRealtime && time < tmpTime)
						endOfBar = false;
					else
					{
						prevTime	= tmpTime;
						tmpTime		= TimeToBarTimeMinute(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue, isRealtime);
						endOfBar	= true;
					}
					break;

				case PeriodType.Volume:
					if (tmpTime == Cbi.Globals.MinDate)
					{
						tmpVolume	= volume;
						endOfBar	= tmpVolume >= bars.Period.BasePeriodValue;
						prevTime	= tmpTime = time;
						if (endOfBar) tmpVolume = 0;
						break;
					}

					tmpVolume	+= volume;
					endOfBar	= tmpVolume >= bars.Period.BasePeriodValue;
					if (endOfBar)
					{
						prevTime	= tmpTime;
						tmpVolume	= 0;
					}
                    tmpTime = time;
                    break;

                case PeriodType.Tick:
                    if (tmpTime == Cbi.Globals.MinDate || bars.Period.BasePeriodValue == 1)
                    {
                        prevTime        = tmpTime == Cbi.Globals.MinDate ? time : tmpTime;
                        tmpTime         = time;
                        tmpTickCount    = bars.Period.BasePeriodValue == 1 ? 0 : 1;
                        endOfBar        = bars.Period.BasePeriodValue == 1;
                        break;
                    }

                    if (tmpTickCount < bars.Period.BasePeriodValue)
                    {
                        tmpTime         = time;
                        endOfBar        = false;
                        tmpTickCount++;
                    }
                    else
                    {
                        prevTime        = tmpTime;
                        tmpTime         = time;
                        endOfBar        = true;
                        tmpTickCount    = 1;
                    }
                    break;

                case PeriodType.Month:
					if (tmpTime == Cbi.Globals.MinDate)
						prevTime = tmpTime = TimeToBarTimeMonth(time, bars.Period.BasePeriodValue);

					if (time.Month <= tmpTime.Month && time.Year == tmpTime.Year || time.Year < tmpTime.Year)
						endOfBar = false;
					else
					{
						prevTime	= tmpTime;
						endOfBar	= true;
						tmpTime		= TimeToBarTimeMonth(time, bars.Period.BasePeriodValue);
					}
					break;

				case PeriodType.Second:
					if (tmpTime == Cbi.Globals.MinDate)
					{
						prevTime = tmpTime = TimeToBarTimeSecond(bars, time,
																	new DateTime(	bars.Session.NextBeginTime.Year,
																					bars.Session.NextBeginTime.Month,
																					bars.Session.NextBeginTime.Day,
																					bars.Session.NextBeginTime.Hour,
																					bars.Session.NextBeginTime.Minute, 0),
																	bars.Period.BasePeriodValue);
					}
					if ((bars.Period.Value > 1 && time < tmpTime) || (bars.Period.Value == 1 && time <= tmpTime))
						endOfBar	= false;
					else
					{
						prevTime	= tmpTime;
						tmpTime		= TimeToBarTimeSecond(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue);
						endOfBar	= true;
					}
					break;

				case PeriodType.Week:
					if (tmpTime == Cbi.Globals.MinDate)
						prevTime = tmpTime = TimeToBarTimeWeek(time.Date, tmpTime.Date, bars.Period.BasePeriodValue);
					if (time.Date <= tmpTime.Date)
						endOfBar = false;
					else
					{
						prevTime	= tmpTime;
						endOfBar	= true;
						tmpTime		= TimeToBarTimeWeek(time.Date, tmpTime.Date, bars.Period.BasePeriodValue);
					}
					break;

				case PeriodType.Year:
					if (tmpTime == Cbi.Globals.MinDate)
						prevTime = tmpTime = TimeToBarTimeYear(time, bars.Period.Value);
					if (time.Year <= tmpTime.Year)
						endOfBar = false;
					else
					{
						prevTime	= tmpTime;
						endOfBar	= true;
						tmpTime		= TimeToBarTimeYear(time, bars.Period.Value);
					}
					break;
			}
			#endregion
			#region Kagi Logic

			reversalPoint = bars.Period.ReversalType == ReversalType.Tick ? bars.Period.Value * bars.Instrument.MasterInstrument.TickSize : bars.Period.Value * 0.01 * anchorPrice;

			if (bars.Count == 0 || (IsIntraday && ((bars.Period.BasePeriodType != PeriodType.Second && bars.IsNewSession(time, isRealtime))
									|| (bars.Period.BasePeriodType == PeriodType.Second && bars.IsNewSession(tmpTime, isRealtime)))))
			{
				if (bars.Count > 0)
				{
					double		lastOpen		= bars.GetOpen(bars.Count - 1);
					double		lastHigh		= bars.GetHigh(bars.Count - 1);
					double		lastLow			= bars.GetLow(bars.Count - 1);
					double		lastClose		= bars.GetClose(bars.Count - 1);

					if (bars.Count == tmpCount)
						CalculateKagiBar(bars, lastOpen, lastHigh, lastLow, lastClose, prevTime, volume, isRealtime);
				}

				AddBar(bars, close, close, close, close, tmpTime, volume, isRealtime);
				anchorPrice		= close;
				trend			= Trend.Undetermined;
				prevTime		= tmpTime;
				volumeCount		= 0;
				bars.LastPrice	= close;
				tmpCount		= bars.Count;
				return;
			}

			Bar		bar		= (Bar)bars.Get(bars.Count - 1);
			double	c		= bar.Close;
			double	o		= bar.Open;
			double	h		= bar.High;
			double	l		= bar.Low;

			if (endOfBar)
				CalculateKagiBar(bars, o, h, l, c, prevTime, volume, isRealtime);
			else
				volumeCount += volume;

			bars.LastPrice	= close;
			tmpCount		= bars.Count;

			#endregion
		}
예제 #11
0
        protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask)
        {
            // method variables
            bool   isNewSession = SessionIterator.IsNewSession(time, isBar);
            double tickSize     = bars.Instrument.MasterInstrument.TickSize;

            if (SessionIterator == null)
            {
                SessionIterator = new SessionIterator(bars);
            }

            if (isNewSession)
            {
                SessionIterator.GetNextSession(time, isBar);
            }

            if (bars.Count == 0 || (bars.IsResetOnNewTradingDay && isNewSession))
            {
                // update fields
                rangeMax = AddTwoDoubles(bars, bars.BarsPeriod.BaseBarsPeriodValue * tickSize, 0);
                rangeMin = AddTwoDoubles(bars, bars.BarsPeriod.Value * tickSize, 0);

                // set initial range, factoring dynamic
                thisRange = isDynamic ? rangeMin : rangeMax;
                AdjustMaxMin(bars, close, close);

                // add first bar
                AddBar(bars, thisOpen, thisOpen, thisOpen, thisOpen, time, volume);
            }
            else
            {
                // local variables
                double barOpen    = bars.GetOpen(bars.Count - 1);
                double barHigh    = bars.GetHigh(bars.Count - 1);
                double barLow     = bars.GetLow(bars.Count - 1);
                int    maxCompare = bars.Instrument.MasterInstrument.Compare(close, thisMax);
                int    minCompare = bars.Instrument.MasterInstrument.Compare(close, thisMin);
                double thisClose  = maxCompare > 0 ? Math.Min(close, thisMax) : minCompare < 0 ? Math.Max(close, thisMin) : close;

                // range exceeded; create new bar(s)
                if (maxCompare > 0 || minCompare < 0)
                {
                    // local variables
                    bool newBar = true;

                    // update bias
                    prevBias = thisBias;
                    thisBias = close > barOpen ? 1 : close < barOpen ? -1 : 0;

                    // close current bar; volume included for on-touch only
                    // see this post for more info on volume calculation: http://www.ninjatrader.com/support/forum/showthread.php?p=302208#post302208
                    UpdateBar(bars, (maxCompare > 0 ? thisClose : barHigh), (minCompare < 0 ? thisClose : barLow), thisClose, time, 0);

                    // add next bar and loop phantom bars, if needed
                    do
                    {
                        // update thisRange for dynamic
                        if (isDynamic)
                        {
                            // increment range for same bias, if range has not exceeded max
                            if ((thisBias == prevBias || prevBias == 0) && thisRange < rangeMax)
                            {
                                thisRange = AddTwoDoubles(bars, thisRange, tickSize);
                            }

                            // increment range after trend change (will only fire once)
                            else if (thisBias != prevBias && prevBias != 0)
                            {
                                thisRange = AddTwoDoubles(bars, rangeMin, tickSize);
                            }

                            // ensure valid range
                            thisRange = Math.Min(thisRange, rangeMax);
                        }

                        // update fields
                        AdjustMaxMin(bars, thisClose, close);
                        thisClose = (maxCompare > 0) ? Math.Min(close, thisMax) : (minCompare < 0) ? Math.Max(close, thisMin) : close;

                        // add new bar; include volume once (except for on-touch), then create phantom bars
                        // see this post for more info on volume calculation: http://www.ninjatrader.com/support/forum/showthread.php?p=302208#post302208
                        AddBar(bars, thisOpen, (maxCompare > 0 ? thisClose : thisOpen), (minCompare < 0 ? thisClose : thisOpen), thisClose, time, (newBar ? volume : 0));
                        newBar = false;

                        // update fields
                        maxCompare = bars.Instrument.MasterInstrument.Compare(close, thisMax);
                        minCompare = bars.Instrument.MasterInstrument.Compare(close, thisMin);
                    }while (maxCompare > 0 || minCompare < 0);
                }
                else
                {
                    UpdateBar(bars, (close > barHigh ? close : barHigh), (close < barLow ? close : barLow), close, time, volume);
                }
            }
            bars.LastPrice = close;
        }
예제 #12
0
        protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask)
        {
            double lastBarClose = bars.GetClose(bars.Count - 1);                 // Trae el último precio de cierre

            if (SessionIterator == null)
            {
                SessionIterator = new SessionIterator(bars);
            }

            offset = bars.BarsPeriod.Value * bars.Instrument.MasterInstrument.TickSize;             // Periocidad * tick (Tamaño de la caja)
            bool isNewSession = SessionIterator.IsNewSession(time, isBar);

            if (isNewSession)
            {
                SessionIterator.GetNextSession(time, isBar);
            }

            // Si es una gráfica nueva o una sesión nueva y está en un nuevo día
            if (bars.Count == 0 || bars.IsResetOnNewTradingDay && isNewSession)
            {
                // una sesión nueva y está en un nuevo día
                if (bars.Count > 0)
                {
                    // Close out last bar in session and set open == close
                    DateTime lastBarTime   = bars.GetTime(bars.Count - 1);                                            // Trae la última fecha del precio de cierre
                    long     lastBarVolume = bars.GetVolume(bars.Count - 1);                                          // Trae el último volumen de precio de cierre
                    RemoveLastBar(bars);                                                                              // Elimina la última barra
                    AddBar(bars, lastBarClose, lastBarClose, lastBarClose, lastBarClose, lastBarTime, lastBarVolume); // Crea una nueva barra con la información obtenida
                }

                renkoHigh = close + offset;                       // Suma el valor de cierre y tamaño de la caja
                renkoLow  = close - offset;                       // Diferencia del valor de cierre y el tamaño de la caja

                // ¿Hay un nuevo precio negociado?
                isNewSession = SessionIterator.IsNewSession(time, isBar);
                if (isNewSession)
                {
                    SessionIterator.GetNextSession(time, isBar);                     // Entonces traiga el último precio
                }
                // Pinte el último precio negociado
                AddBar(bars, close, close, close, close, time, volume);
                bars.LastPrice = close;

                return;
            }

            double   barOpen   = bars.GetOpen(bars.Count - 1);                            // Obtiene el valor de apertura de la última barra
            double   barHigh   = bars.GetHigh(bars.Count - 1);                            // Obtiene el valor más alto negociado de la última barra
            double   barLow    = bars.GetLow(bars.Count - 1);                             // Obtiene el valor más bajo negociado de la última barra
            long     barVolume = bars.GetVolume(bars.Count - 1);                          // Obtiene el volumen de la última barra
            DateTime barTime   = bars.GetTime(bars.Count - 1);                            // Obtiene la fecha de la última barra

            // renkoHigh == 0 || renkoLow == 0
            // ApproxCompare: Compares two double or float values for equality or being greater than / less than the compared to value.
            if (renkoHigh.ApproxCompare(0.0) == 0 || renkoLow.ApproxCompare(0.0) == 0)
            {
                if (bars.Count == 1)
                {
                    renkoHigh = barOpen + offset;                           // suma = valor de apertura de la última barra + el tamaño de la caja
                    renkoLow  = barOpen - offset;                           // diferencia = valor de apertura de la última barra - el tamaño de la caja
                }
                // Penultimo valor de cierre es mayor al penultimo valor de apertura?
                else if (bars.GetClose(bars.Count - 2) > bars.GetOpen(bars.Count - 2))
                {
                    renkoHigh = bars.GetClose(bars.Count - 2) + offset;                                 // Suma tamaño de la caja + el penultimo valor de cierre
                    renkoLow  = bars.GetClose(bars.Count - 2) - offset * 2;                             // Resta el doble del tamaño de la caja - el penultimo valor de cierre
                }
                else
                {
                    renkoHigh = bars.GetClose(bars.Count - 2) + offset * 2;                             // Suma el doble tamaño de la caja + el penultimo valor de cierre
                    renkoLow  = bars.GetClose(bars.Count - 2) - offset;                                 // Resta el tamaño de la caja - el penultimo valor de cierre
                }
            }

            bool isRail2Rail = false;

            // Hay cambio de tendencia hacia bajista?
            if (close <= (renkoHigh))
            {
                // Elimina la barra de Update
                RemoveLastBar(bars);

                // Agrega la nueva barra con los nuevos valores
                renkoLow  = renkoHigh - 2.0 * offset;                       // RenkoHigh - el doble del tamaño de la caja
                renkoHigh = renkoHigh + offset;                             // Renkohigh + el tamaño de la caja
                // Agrega barra alcista
                //AddBar(bars, _renkoLow - offset, Math.Max(_renkoLow - offset, _renkoLow), Math.Min(_renkoLow - offset, _renkoLow), _renkoLow, barTime, barVolume);
                //AddBar(bars, _renkoHigh + offset, Math.Max(_renkoHigh + offset, _renkoHigh), Math.Min(_renkoHigh + offset, _renkoHigh), _renkoHigh, barTime, barVolume);
                //AddBar(Bars bars, double open, double high, double low, double close, DateTime time, long volume)

                //Barra de una gráfica bajista
                AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, barTime, barVolume);

                isRail2Rail = true;
            }
            //bool isRail2Rail = false;
            // Hay cambio de tendencia hacia alcista?
            if (close >= (renkoLow))
            {
                // Elimina la barra la barra de Update
                RemoveLastBar(bars);
                // Agrega la nueva barra con los nuevos valores
                // Original
                //AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, barTime, barVolume);
                // Bajista
                renkoHigh = renkoLow + 2.0 * offset;                            // RenkoLow - el doble del tamaño de la caja
                renkoLow  = renkoLow - offset;                                  // RenkoLow - el tamaño de la caja
                //AddBar(bars, _renkoHigh + offset, Math.Max(_renkoHigh + offset, _renkoHigh), Math.Min(_renkoHigh + offset, _renkoHigh), _renkoHigh, barTime, barVolume);
                //AddBar(bars, _renkoLow - offset, Math.Max(_renkoLow - offset, _renkoLow), Math.Min(_renkoLow - offset, _renkoLow), _renkoLow, barTime, barVolume);

                //Barra de gráfica alcista
                AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, renkoHigh), Math.Min(renkoHigh - offset, renkoHigh), renkoHigh, barTime, barVolume);

                isRail2Rail = true;
            }
            // el precio de cierre es mayor renkohigh?
            // [DETECTA COMPORTAMIENTO ALCISTA]
            if (close.ApproxCompare(renkoHigh) >= 0)
            {
                /* if (trend != 0 && trend != 1) {
                 *      // Elimina la barra de Update
                 *      RemoveLastBar(bars);
                 *
                 *      // Agrega la nueva barra con los nuevos valores
                 *      var _renkoLow	= renkoHigh - 1.0 * offset; // RenkoHigh - el doble del tamaño de la caja
                 *      var _renkoHigh	= renkoHigh + offset;		// Renkohigh + el tamaño de la caja
                 *      // Agrega barra alcista
                 *      AddBar(bars, _renkoLow - offset, Math.Max(_renkoLow - offset, _renkoLow), Math.Min(_renkoLow - offset, _renkoLow), _renkoLow, barTime, barVolume);
                 *
                 *      isRail2Rail = true;
                 * } */
                // (1) Obtiene el valor mayor entre renkoHigh y, renkoHigh - tamaño de la caja
                // (2) Si el valor de x es igual a y entonces retorna 0
                //		Si el valor de x es mayor a y entonces retorna 1
                //		Si el valor de x es menor a y entonces retorna -1
                if (barOpen.ApproxCompare(renkoHigh - offset) != 0 ||              // valor de apertura de la (última barra - el tamño de la caja) es mayor o menor a barOpen?
                    barHigh.ApproxCompare(Math.Max(renkoHigh - offset, renkoHigh)) != 0 ||                     // Es barHigh mayor o menor a (1)?
                    barLow.ApproxCompare(Math.Min(renkoHigh - offset, renkoHigh)) != 0)                       // Es barLow mayor o menor a (1)?
                {
                    // No hubo cambio de tendencia
                    if (!isRail2Rail)
                    {
                        // Elimina la última barra de Update
                        RemoveLastBar(bars);
                    }

                    // Agrega una barra nueva con los nuevos valores
                    // Alcista
                    AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, renkoHigh), Math.Min(renkoHigh - offset, renkoHigh), renkoHigh, barTime, barVolume);
                }

                renkoLow  = renkoHigh - 2.0 * offset;                       // RenkoHigh - el doble del tamaño de la caja
                renkoHigh = renkoHigh + offset;                             // Renkohigh + el tamaño de la caja

                // ¿Hay un nuevo valor negociado?
                isNewSession = SessionIterator.IsNewSession(time, isBar);
                if (isNewSession)
                {
                    SessionIterator.GetNextSession(time, isBar);                     // Obtiene el último valor negociado
                }
                // Agrega barras vacías para llenar el gap si el precio salta
                while (close.ApproxCompare(renkoHigh) >= 0)
                {
                    AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, renkoHigh), Math.Min(renkoHigh - offset, renkoHigh), renkoHigh, time, 0);
                    renkoLow  = renkoHigh - 2.0 * offset;
                    renkoHigh = renkoHigh + offset;
                }

                // Agrega la barra final parcial
                AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, close), Math.Min(renkoHigh - offset, close), close, time, volume);
                trend = 1;
            }
            // el precio de cierre es menor o igual a renkohigh?
            // El precio de cierre es menor o igual al renkolow
            // [DETECTA COMPORTAMIENTO BAJISTA]
            else if (close.ApproxCompare(renkoLow) <= 0)
            {
                /* if (trend != 0 && trend != -1) {
                 *      // Elimina la barra la barra de Update
                 *      RemoveLastBar(bars);
                 *      // Agrega la nueva barra con los nuevos valores
                 *      // Original
                 *      //AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, barTime, barVolume);
                 *      // Bajista
                 *      var _renkoHigh	= renkoLow + 1.0 * offset;	// RenkoLow - el doble del tamaño de la caja
                 *      var _renkoLow	= renkoLow - offset;		// RenkoLow - el tamaño de la caja
                 *      AddBar(bars, _renkoHigh + offset, Math.Max(_renkoHigh + offset, _renkoHigh), Math.Min(_renkoHigh + offset, _renkoHigh), _renkoHigh, barTime, barVolume);
                 *      isRail2Rail = true;
                 * } */
                // (1) Obtiene el valor mayor entre renkoLow y, renkoLow + tamaño de la caja
                // (2) Si el valor de x es igual a y entonces retorna 0
                //		Si el valor de x es mayor a y entonces retorna 1
                //		Si el valor de x es menor a y entonces retorna -1
                if (barOpen.ApproxCompare(renkoLow + offset) != 0 ||              // Valor de apertura de (renkolow + el tamaño de la caja) es mayor o menor a barOpen?
                    barHigh.ApproxCompare(Math.Max(renkoLow + offset, renkoLow)) != 0 ||                     // Es barHigh mayor o menor a (1)?
                    barLow.ApproxCompare(Math.Min(renkoLow + offset, renkoLow)) != 0)                         // Es barlow mayor o menor a (1)?
                {
                    // TODO: Validar si la condición cambia, si si, entonces no elimine la última barra
                    if (!isRail2Rail)
                    {
                        // Elimine la barra de Update
                        RemoveLastBar(bars);
                    }

                    // Agrega la nueva barra con los nuevos valores
                    // AddBar(Bars bars, double open, double high, double low, double close, DateTime time, long volume)
                    //Bajista
                    AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, barTime, barVolume);
                }

                renkoHigh = renkoLow + 2.0 * offset;                            // RenkoLow - el doble del tamaño de la caja
                renkoLow  = renkoLow - offset;                                  // RenkoLow - el tamaño de la caja

                // ¿Hay un nuevo valor negociado?
                isNewSession = SessionIterator.IsNewSession(time, isBar);
                if (isNewSession)
                {
                    SessionIterator.GetNextSession(time, isBar);                      // Obtiene el último valor negociado
                }
                // Agrega barras vacías para llenar el gap si el precio salta
                while (close.ApproxCompare(renkoLow) <= 0)
                {
                    AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, time, 0);
                    renkoHigh = renkoLow + 2.0 * offset;
                    renkoLow  = renkoLow - offset;
                }

                // Agrega la barra final parcial
                AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, close), Math.Min(renkoLow + offset, close), close, time, volume);
                trend = -1;
            }
            // El precio de cierre mayor al renkolow
            else
            {
                // Actualiza la barra
                UpdateBar(bars, close, close, close, time, volume);
            }

            // El último precio el valor de cierre
            bars.LastPrice = close;
        }
예제 #13
0
파일: BoxStyle.cs 프로젝트: theprofe8/nt8
        public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars)
        {
            Bars       bars      = chartBars.Bars;
            float      chartMinX = ConvertToHorizontalPixels(chartControl, chartControl.CanvasLeft + chartControl.Properties.BarMarginRight);
            RectangleF rect      = new RectangleF();
            int        toIndex   = chartBars.ToIndex;

            if (toIndex >= 0 && toIndex < bars.Count - 1)
            {
                toIndex++;
            }

            for (int idx = chartBars.FromIndex; idx <= toIndex; idx++)
            {
                double closeValue             = bars.GetClose(idx);
                float  high                   = chartScale.GetYByValue(bars.GetHigh(idx));
                float  low                    = chartScale.GetYByValue(bars.GetLow(idx));
                double openValue              = bars.GetOpen(idx);
                Brush  overriddenBarBrush     = chartControl.GetBarOverrideBrush(chartBars, idx);
                Brush  overriddenOutlineBrush = chartControl.GetCandleOutlineOverrideBrush(chartBars, idx);
                float  x = chartControl.GetXByBarIndex(chartBars, idx);
                float  boxStartPosition;

                if (idx == chartBars.FromIndex && (toIndex == 0 || idx == 0))
                {
                    if (toIndex == 0)
                    {
                        boxStartPosition = chartMinX;
                    }
                    else
                    {
                        boxStartPosition = 2 * x - chartControl.GetXByBarIndex(chartBars, idx + 1);
                    }
                }
                else
                {
                    boxStartPosition = chartControl.GetXByBarIndex(chartBars, idx - 1);
                }

                if (Math.Abs(x - boxStartPosition) < 0.2)
                {
                    continue;
                }

                float width = Math.Max(2f, Math.Abs(x - boxStartPosition));

                if (closeValue > openValue)
                {
                    width      -= Stroke.Width;
                    rect.X      = boxStartPosition;
                    rect.Y      = high;
                    rect.Width  = width;
                    rect.Height = low - high;
                    TransformBrush(overriddenBarBrush ?? UpBrushDX, rect);
                    TransformBrush(overriddenOutlineBrush ?? Stroke.BrushDX, rect);
                    RenderTarget.FillRectangle(rect, overriddenBarBrush ?? UpBrushDX);
                    RenderTarget.DrawRectangle(rect, overriddenOutlineBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle);
                }
                else
                {
                    width      -= Stroke2.Width;
                    rect.X      = boxStartPosition;
                    rect.Y      = high;
                    rect.Width  = width;
                    rect.Height = low - high;
                    TransformBrush(overriddenBarBrush ?? DownBrushDX, rect);
                    TransformBrush(overriddenOutlineBrush ?? Stroke2.BrushDX, rect);
                    RenderTarget.FillRectangle(rect, overriddenBarBrush ?? DownBrushDX);
                    RenderTarget.DrawRectangle(rect, overriddenOutlineBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle);
                }
            }
        }
예제 #14
0
		/// <summary>
		/// </summary>
		/// <param name="bars"></param>
		/// <param name="open"></param>
		/// <param name="high"></param>
		/// <param name="low"></param>
		/// <param name="close"></param>
		/// <param name="time"></param>
		/// <param name="volume"></param>
		/// <param name="isRealtime"></param>
		public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime)
		{
			#region Building Bars from Base Period

			if (bars.Count != tmpCount) // reset cache when bars are trimmed
				if (bars.Count == 0)
				{
					tmpTime			= Cbi.Globals.MinDate;
					tmpVolume		= 0;
					tmpDayCount		= 0;
					tmpTickCount	= 0;
				}
				else
				{
					tmpTime			= bars.GetTime(bars.Count - 1);
					tmpVolume		= bars.GetVolume(bars.Count - 1);
					tmpTickCount	= bars.TickCount;
					tmpDayCount		= bars.DayCount;
					bars.LastPrice	= anchorPrice = bars.GetClose(bars.Count - 1);
				}

			switch (bars.Period.BasePeriodType)
			{
				case PeriodType.Day:
					tmpTime = time.Date;
					if (isRealtime && time >= cacheSessionEnd)
					{
						tmpDayCount++;
						bars.Session.GetSessionDate(time, false, out tmpTime, out cacheSessionEnd);
						if (tmpTime < time.Date) tmpTime = time.Date; // make sure timestamps are ascending
					}

					if (!isRealtime && prevTimeD != tmpTime) tmpDayCount++;

					if ((!isRealtime && bars.Count > 0 && tmpTime == bars.TimeLastBar.Date)
						|| (isRealtime && bars.Count > 0 && tmpTime <= bars.TimeLastBar.Date)
						|| tmpDayCount < bars.Period.BasePeriodValue)
						endOfBar = false;
					else
					{
						prevTime	= prevTimeD == Cbi.Globals.MinDate ? tmpTime : prevTimeD;
						prevTimeD	= tmpTime;
						endOfBar	= true;
					}

					break;

				case PeriodType.Minute:

					if (tmpTime == Cbi.Globals.MinDate)
						prevTime = tmpTime = TimeToBarTimeMinute(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue, isRealtime);

					if (!isRealtime && time <= tmpTime || isRealtime && time < tmpTime)
						endOfBar	= false;
					else
					{
						prevTime	= tmpTime;
						tmpTime		= TimeToBarTimeMinute(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue, isRealtime);
						endOfBar	= true;
					}
					break;

				case PeriodType.Volume:
					if (tmpTime == Cbi.Globals.MinDate)
					{
						tmpVolume	= volume;
						endOfBar	= tmpVolume >= bars.Period.BasePeriodValue;
						prevTime	= tmpTime = time;
						if (endOfBar) 
							tmpVolume = 0;
						break;
					}

					tmpVolume += volume;
					endOfBar = tmpVolume >= bars.Period.BasePeriodValue;
					if (endOfBar)
					{
						prevTime = tmpTime;
						tmpVolume = 0;
						tmpTime = time;
					}
					break;

				case PeriodType.Month:
					if (tmpTime == Cbi.Globals.MinDate)
						prevTime	= tmpTime = TimeToBarTimeMonth(time, bars.Period.BasePeriodValue);

					if (time.Month <= tmpTime.Month && time.Year == tmpTime.Year || time.Year < tmpTime.Year)
						endOfBar	= false;
					else
					{
						prevTime	= tmpTime;
						endOfBar	= true;
						tmpTime		= TimeToBarTimeMonth(time, bars.Period.BasePeriodValue);
					}
					break;

				case PeriodType.Second:
					if (tmpTime == Cbi.Globals.MinDate)
					{
						prevTime = tmpTime = TimeToBarTimeSecond(bars, time,
																	new DateTime(bars.Session.NextBeginTime.Year,
																				bars.Session.NextBeginTime.Month,
																				bars.Session.NextBeginTime.Day,
																				bars.Session.NextBeginTime.Hour,
																				bars.Session.NextBeginTime.Minute, 0),
																	bars.Period.BasePeriodValue);
					}
					if (time <= tmpTime)
						endOfBar	= false;
					else
					{
						prevTime	= tmpTime;
						tmpTime		= TimeToBarTimeSecond(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue);
						endOfBar	= true;
					}
					break;

				case PeriodType.Tick:
					if (tmpTime == Cbi.Globals.MinDate || bars.Period.BasePeriodValue == 1)
					{
						prevTime		= tmpTime = time;
						tmpTickCount	= bars.Period.BasePeriodValue == 1 ? 0 : 1;
						endOfBar		= bars.Period.BasePeriodValue == 1;
						break;
					}

					if (tmpTickCount < bars.Period.BasePeriodValue)
					{
						tmpTime			= time;
						endOfBar		= false;
						tmpTickCount++;
					}
					else
					{
						prevTime		= tmpTime;
						tmpTime			= time;
						endOfBar		= true;
						tmpTickCount	= 1;
					}
					break;

				case PeriodType.Week:
					if (tmpTime == Cbi.Globals.MinDate)
						prevTime = tmpTime = TimeToBarTimeWeek(time.Date, tmpTime.Date, bars.Period.BasePeriodValue);
					if (time.Date <= tmpTime.Date)
						endOfBar	= false;
					else
					{
						prevTime	= tmpTime;
						endOfBar	= true;
						tmpTime		= TimeToBarTimeWeek(time.Date, tmpTime.Date, bars.Period.BasePeriodValue);
					}
					break;

				case PeriodType.Year:
					if (tmpTime == Cbi.Globals.MinDate)
						prevTime = tmpTime = TimeToBarTimeYear(time, bars.Period.Value);
					if (time.Year <= tmpTime.Year)
						endOfBar	= false;
					else
					{
						prevTime	= tmpTime;
						endOfBar	= true;
						tmpTime		= TimeToBarTimeYear(time, bars.Period.Value);
					}
					break;
				default:
					break;
			}
			#endregion
			#region P&F logic
			double tickSize		= bars.Instrument.MasterInstrument.TickSize;
			boxSize				= Math.Floor(10000000.0 * bars.Period.Value * tickSize) / 10000000.0;
			reversalSize		= bars.Period.Value2 * boxSize;

			if (bars.Count == 0 || (IsIntraday && bars.IsNewSession(time, isRealtime)))
			{
				if (bars.Count > 0)
				{
					double		lastOpen	= bars.GetOpen(bars.Count - 1);
					double		lastHigh	= bars.GetHigh(bars.Count - 1);
					double		lastLow		= bars.GetLow(bars.Count - 1);
					double		lastClose	= bars.GetClose(bars.Count - 1);
					DateTime	lastTime	= bars.GetTime(bars.Count - 1);
					bars.LastPrice			= anchorPrice = lastClose;

					if (bars.Count == tmpCount)
						CalculatePfBar(bars, lastOpen, lastHigh, lastLow, lastClose, prevTime, lastTime, isRealtime);
				}

				AddBar(bars, close, close, close, close, tmpTime, volume, isRealtime);
				anchorPrice		= close;
				trend			= Trend.Undetermined;
				prevTime		= tmpTime;
				volumeCount		= 0;
				bars.LastPrice	= close;
				tmpCount		= bars.Count;
				tmpHigh			= high;
				tmpLow			= low;
				return;
			}

			Bar			bar		= (Bar)bars.Get(bars.Count - 1);
			double		c		= bar.Close;
			double		o		= bar.Open;
			double		h		= bar.High;
			double		l		= bar.Low;
			DateTime	t		= bar.Time;

			if (endOfBar)
			{
				CalculatePfBar(bars, o, h, l, c, prevTime, t, isRealtime);
				volumeCount		= volume;
				tmpHigh			= high;
				tmpLow			= low;
			}
			else
			{
				tmpHigh			= (high > tmpHigh ? high : tmpHigh);
				tmpLow			= (low < tmpLow ? low : tmpLow);
				volumeCount		+= volume;
			}

			bars.LastPrice		= close;
			tmpCount			= bars.Count;

			#endregion
		}
예제 #15
0
        protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask)
        {
            if (SessionIterator == null)
            {
                SessionIterator = new SessionIterator(bars);
            }

            double haClose = 0.0;
            double haHigh  = 0.0;
            double haLow   = 0.0;
            double haOpen  = 0.0;

            switch (BarsPeriod.BaseBarsPeriodType)
            {
            case BarsPeriodType.Day:
            {
                if (bars.Count == 0)
                {
                    if (isBar || bars.TradingHours.Sessions.Count == 0)
                    {
                        AddBar(bars, open, high, low, close, time.Date, volume);
                    }
                    else
                    {
                        SessionIterator.CalculateTradingDay(time, false);
                        AddBar(bars, open, high, low, close, SessionIterator.ActualTradingDayExchange, volume);
                    }
                }
                else
                {
                    DateTime barTime;
                    if (isBar)
                    {
                        barTime = time.Date;
                    }
                    else
                    {
                        if (bars.TradingHours.Sessions.Count > 0 && SessionIterator.IsNewSession(time, false))
                        {
                            SessionIterator.CalculateTradingDay(time, false);
                            barTime = SessionIterator.ActualTradingDayExchange;
                            if (barTime < bars.LastBarTime.Date)
                            {
                                barTime = bars.LastBarTime.Date;                                                 // Make sure timestamps are ascending
                            }
                        }
                        else
                        {
                            barTime = bars.LastBarTime.Date;                                             // Make sure timestamps are ascending
                        }
                    }

                    if (bars.DayCount < bars.BarsPeriod.BaseBarsPeriodValue ||
                        isBar && bars.Count > 0 && barTime == bars.LastBarTime.Date ||
                        !isBar && bars.Count > 0 && barTime <= bars.LastBarTime.Date)
                    {
                        haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                        haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1)));
                        haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1)));
                        UpdateBar(bars, haHigh, haLow, haClose, barTime, volume);
                    }
                    else
                    {
                        haOpen  = bars.Instrument.MasterInstrument.RoundToTickSize((bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0);
                        haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                        haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen));
                        haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen));
                        AddBar(bars, haOpen, haHigh, haLow, haClose, barTime, volume);
                    }
                }

                break;
            }

            case BarsPeriodType.Minute:
            {
                if (bars.Count == 0)
                {
                    AddBar(bars, open, high, low, close, TimeToBarTimeMinute(bars, time, isBar), volume);
                }
                else if (!isBar && time < bars.LastBarTime)
                {
                    haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                    haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1)));
                    haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1)));
                    UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume);
                }
                else if (isBar && time <= bars.LastBarTime)
                {
                    haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                    haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1)));
                    haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1)));
                    UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume);
                }
                else
                {
                    haOpen  = bars.Instrument.MasterInstrument.RoundToTickSize((bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0);
                    haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                    haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen));
                    haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen));
                    time    = TimeToBarTimeMinute(bars, time, isBar);
                    AddBar(bars, haOpen, haHigh, haLow, haClose, time, volume);
                }

                break;
            }

            case BarsPeriodType.Month:
            {
                if (bars.Count == 0)
                {
                    AddBar(bars, open, high, low, close, TimeToBarTimeMonth(time, bars.BarsPeriod.BaseBarsPeriodValue), volume);
                }
                else if (time.Month <= bars.LastBarTime.Month && time.Year == bars.LastBarTime.Year || time.Year < bars.LastBarTime.Year)
                {
                    if (high.ApproxCompare(bars.GetHigh(bars.Count - 1)) != 0 || low.ApproxCompare(bars.GetLow(bars.Count - 1)) != 0 || close.ApproxCompare(bars.GetClose(bars.Count - 1)) != 0 || volume > 0)
                    {
                        haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                        haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1)));
                        haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1)));
                        UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume);
                    }
                }
                else
                {
                    haOpen  = bars.Instrument.MasterInstrument.RoundToTickSize((bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0);
                    haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                    haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen));
                    haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen));
                    AddBar(bars, haOpen, haHigh, haLow, haClose, TimeToBarTimeMonth(time, bars.BarsPeriod.BaseBarsPeriodValue), volume);
                }
                break;
            }

            case BarsPeriodType.Second:
            {
                if (bars.Count == 0)
                {
                    DateTime barTime = TimeToBarTimeSecond(bars, time, isBar);
                    AddBar(bars, open, high, low, close, barTime, volume);
                }
                else
                {
                    if (bars.BarsPeriod.BaseBarsPeriodValue > 1 && time < bars.LastBarTime || bars.BarsPeriod.BaseBarsPeriodValue == 1 && time <= bars.LastBarTime)
                    {
                        haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                        haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1)));
                        haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1)));
                        UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume);
                    }
                    else
                    {
                        haOpen  = bars.Instrument.MasterInstrument.RoundToTickSize((bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0);
                        haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                        haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen));
                        haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen));
                        time    = TimeToBarTimeSecond(bars, time, isBar);
                        AddBar(bars, haOpen, haHigh, haLow, haClose, time, volume);
                    }
                }
                break;
            }

            case BarsPeriodType.Tick:
            {
                bool isNewSession = SessionIterator.IsNewSession(time, isBar);
                if (isNewSession)
                {
                    SessionIterator.GetNextSession(time, isBar);
                }

                if (bars.BarsPeriod.BaseBarsPeriodValue == 1)
                {
                    haOpen  = haOpen.ApproxCompare(0.0) == 0 ? open : (haOpen + haClose) / 2.0;
                    haClose = haClose.ApproxCompare(0.0) == 0 ? close : bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                    haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen));
                    haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen));
                    AddBar(bars, haOpen, haHigh, haLow, haClose, time, volume);
                }
                else if (bars.Count == 0)
                {
                    AddBar(bars, open, high, low, close, time, volume);
                }
                else if (bars.Count > 0 && (!isNewSession || !bars.IsResetOnNewTradingDay) && bars.BarsPeriod.BaseBarsPeriodValue > 1 && bars.TickCount < bars.BarsPeriod.BaseBarsPeriodValue)
                {
                    haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                    haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1)));
                    haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1)));
                    UpdateBar(bars, haHigh, haLow, haClose, time, volume);
                }
                else
                {
                    haOpen  = bars.Instrument.MasterInstrument.RoundToTickSize((bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0);
                    haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                    haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen));
                    haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen));
                    AddBar(bars, haOpen, haHigh, haLow, haClose, time, volume);
                }
                break;
            }

            case BarsPeriodType.Volume:
            {
                if (bars.Count == 0)
                {
                    while (volume > bars.BarsPeriod.BaseBarsPeriodValue)
                    {
                        haOpen  = haOpen.ApproxCompare(0.0) == 0 ? open : (haOpen + haClose) / 2.0;
                        haClose = haClose.ApproxCompare(0) == 0 ? close : bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                        haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen));
                        haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen));
                        AddBar(bars, haOpen, haHigh, haLow, haClose, time, bars.BarsPeriod.BaseBarsPeriodValue);
                        volume -= bars.BarsPeriod.BaseBarsPeriodValue;
                    }
                    if (volume > 0)
                    {
                        haOpen  = haOpen.ApproxCompare(0.0) == 0 ? open : bars.Instrument.MasterInstrument.RoundToTickSize((haOpen + haClose) / 2.0);
                        haClose = haClose.ApproxCompare(0.0) == 0 ? close : bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                        haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen));
                        haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen));
                        AddBar(bars, haOpen, haHigh, haLow, haClose, time, volume);
                    }
                }
                else
                {
                    long volumeTmp    = 0;
                    bool isNewSession = SessionIterator.IsNewSession(time, isBar);
                    if (!bars.IsResetOnNewTradingDay || !isNewSession)
                    {
                        volumeTmp = Math.Min(bars.BarsPeriod.BaseBarsPeriodValue - bars.GetVolume(bars.Count - 1), volume);
                        if (volumeTmp > 0)
                        {
                            haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                            haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1)));
                            haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1)));
                            UpdateBar(bars, haHigh, haLow, haClose, time, volumeTmp);
                        }
                    }

                    if (isNewSession)
                    {
                        SessionIterator.GetNextSession(time, isBar);
                    }

                    volumeTmp = volume - volumeTmp;
                    while (volumeTmp > 0)
                    {
                        haOpen  = bars.Instrument.MasterInstrument.RoundToTickSize((bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0);
                        haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                        haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen));
                        haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen));
                        AddBar(bars, haOpen, haHigh, haLow, haClose, time, Math.Min(volumeTmp, bars.BarsPeriod.BaseBarsPeriodValue));
                        volumeTmp -= bars.BarsPeriod.BaseBarsPeriodValue;
                    }
                }

                break;
            }

            case BarsPeriodType.Week:
            {
                if (bars.Count == 0)
                {
                    AddBar(bars, open, high, low, close, TimeToBarTimeWeek(time, time.AddDays(6 - ((int)time.DayOfWeek + 1) % 7 + (bars.BarsPeriod.BaseBarsPeriodValue - 1) * 7), bars.BarsPeriod.BaseBarsPeriodValue), volume);
                }
                else if (time.Date <= bars.LastBarTime.Date)
                {
                    haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                    haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1)));
                    haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1)));
                    UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume);
                }
                else
                {
                    haOpen  = bars.Instrument.MasterInstrument.RoundToTickSize((bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0);
                    haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                    haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen));
                    haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen));
                    AddBar(bars, haOpen, haHigh, haLow, haClose, TimeToBarTimeWeek(time.Date, bars.LastBarTime.Date, bars.BarsPeriod.BaseBarsPeriodValue), volume);
                }

                break;
            }

            case BarsPeriodType.Year:
            {
                if (bars.Count == 0)
                {
                    AddBar(bars, open, high, low, close, TimeToBarTimeYear(time, bars.BarsPeriod.BaseBarsPeriodValue), volume);
                }
                else
                {
                    if (time.Year <= bars.LastBarTime.Year)
                    {
                        haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                        haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1)));
                        haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1)));
                        UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume);
                    }
                    else
                    {
                        haOpen  = bars.Instrument.MasterInstrument.RoundToTickSize((bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0);
                        haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0);
                        haHigh  = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen));
                        haLow   = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen));
                        AddBar(bars, haOpen, haHigh, haLow, haClose, TimeToBarTimeYear(time.Date, bars.BarsPeriod.BaseBarsPeriodValue), volume);
                    }
                }

                break;
            }
            }

            bars.LastPrice = haClose;
        }
예제 #16
0
        public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars)
        {
            Bars       bars     = chartBars.Bars;
            float      barWidth = GetBarPaintWidth(BarWidthUI);
            Vector2    point0   = new Vector2();
            Vector2    point1   = new Vector2();
            RectangleF rect     = new RectangleF();

            for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++)
            {
                Brush  overriddenBarBrush     = chartControl.GetBarOverrideBrush(chartBars, idx);
                Brush  overriddenOutlineBrush = chartControl.GetCandleOutlineOverrideBrush(chartBars, idx);
                double closeValue             = bars.GetClose(idx);
                int    close     = chartScale.GetYByValue(closeValue);
                int    high      = chartScale.GetYByValue(bars.GetHigh(idx));
                int    low       = chartScale.GetYByValue(bars.GetLow(idx));
                double openValue = bars.GetOpen(idx);
                int    open      = chartScale.GetYByValue(openValue);
                int    x         = chartControl.GetXByBarIndex(chartBars, idx);

                if (Math.Abs(open - close) < 0.0000001)
                {
                    // Line
                    point0.X = x - barWidth * 0.5f;
                    point0.Y = close;
                    point1.X = x + barWidth * 0.5f;
                    point1.Y = close;
                    Brush b = overriddenOutlineBrush ?? Stroke.BrushDX;
                    if (!(b is SolidColorBrush))
                    {
                        TransformBrush(overriddenOutlineBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width));
                    }
                    RenderTarget.DrawLine(point0, point1, b, Stroke.Width, Stroke.StrokeStyle);
                }
                else
                {
                    // Candle
                    rect.X      = x - barWidth * 0.5f + 0.5f;
                    rect.Y      = Math.Min(close, open);
                    rect.Width  = barWidth - 1;
                    rect.Height = Math.Max(open, close) - Math.Min(close, open);
                    Brush brush = overriddenBarBrush ?? (closeValue >= openValue ? UpBrushDX : DownBrushDX);
                    if (!(brush is SolidColorBrush))
                    {
                        TransformBrush(brush, rect);
                    }
                    RenderTarget.FillRectangle(rect, brush);
                    brush = overriddenOutlineBrush ?? Stroke.BrushDX;
                    if (!(brush is SolidColorBrush))
                    {
                        TransformBrush(brush, rect);
                    }
                    RenderTarget.DrawRectangle(rect, overriddenOutlineBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle);
                }

                Brush br = overriddenOutlineBrush ?? Stroke2.BrushDX;

                // High wick
                if (high < Math.Min(open, close))
                {
                    point0.X = x;
                    point0.Y = high;
                    point1.X = x;
                    point1.Y = Math.Min(open, close);
                    if (!(br is SolidColorBrush))
                    {
                        TransformBrush(br, new RectangleF(point0.X - Stroke2.Width, point0.Y, Stroke2.Width, point1.Y - point0.Y));
                    }
                    RenderTarget.DrawLine(point0, point1, br, Stroke2.Width, Stroke2.StrokeStyle);
                }

                // Low wick
                if (low > Math.Max(open, close))
                {
                    point0.X = x;
                    point0.Y = low;
                    point1.X = x;
                    point1.Y = Math.Max(open, close);
                    if (!(br is SolidColorBrush))
                    {
                        TransformBrush(br, new RectangleF(point1.X - Stroke2.Width, point1.Y, Stroke2.Width, point0.Y - point1.Y));
                    }
                    RenderTarget.DrawLine(point0, point1, br, Stroke2.Width, Stroke2.StrokeStyle);
                }
            }
        }
예제 #17
0
        public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars)
        {
            if (chartBars.FromIndex > chartBars.ToIndex)
            {
                return;
            }

            if (chartBars.FromIndex > 0)
            {
                chartBars.FromIndex--;
            }

            Bars    bars              = chartBars.Bars;
            float   barWidth          = GetBarPaintWidth(BarWidthUI);
            int     sessionStartIndex = chartBars.FromIndex;
            int     thickOffsetTop    = (int)(Stroke.Width * 0.5);
            int     thinOffsetTop     = (int)(Stroke2.Width * 0.5);
            Vector2 point0            = new Vector2();
            Vector2 point1            = new Vector2();

            while (sessionStartIndex > 0 && bars.BarsType.IsIntraday)
            {
                if (bars.BarsSeries.GetIsFirstBarOfSession(sessionStartIndex))
                {
                    break;
                }
                sessionStartIndex--;
            }

            if (sessionStartIndex < 0)             // Occurs when all bars are off screen
            {
                return;
            }

            thickLine = bars.GetClose(sessionStartIndex) > bars.GetOpen(sessionStartIndex);

            //Determine the next bar coming up is thick or thin
            for (int k = sessionStartIndex + 1; k < chartBars.FromIndex; k++)
            {
                double closeTest = bars.GetClose(k);
                if (closeTest > bars.GetOpen(k))
                {
                    if (Math.Max(bars.GetOpen(k - 1), bars.GetClose(k - 1)) < closeTest)
                    {
                        thickLine = true;
                    }
                }
                else if (closeTest < Math.Min(bars.GetOpen(k - 1), bars.GetClose(k - 1)))
                {
                    thickLine = false;
                }
            }

            for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++)
            {
                Brush  overriddenBrush = chartControl.GetBarOverrideBrush(chartBars, idx);
                double openValue       = bars.GetOpen(idx);
                float  open            = chartScale.GetYByValue(openValue);
                double closeValue      = bars.GetClose(idx);
                float  close           = chartScale.GetYByValue(closeValue);
                float  x              = chartControl.GetXByBarIndex(chartBars, idx);
                double prevOpenValue  = idx == 0 ? openValue : bars.GetOpen(idx - 1);
                double prevCloseValue = idx == 0 ? closeValue : bars.GetClose(idx - 1);

                float startPosition;
                if (idx == 0 && chartBars.ToIndex >= 1)
                {
                    float x0    = chartControl.GetXByBarIndex(chartBars, 0);
                    float x1    = chartControl.GetXByBarIndex(chartBars, 1);
                    float diffX = Math.Max(1, x1 - x0);
                    startPosition = x0 - diffX;
                }
                else
                {
                    startPosition = idx == chartBars.FromIndex ? chartControl.GetXByBarIndex(chartBars, idx) : chartControl.GetXByBarIndex(chartBars, idx - 1);
                }

                startPosition = startPosition < 0 ? 0 : startPosition;

                if (bars.BarsType.IsIntraday && bars.IsResetOnNewTradingDay && bars.BarsSeries.GetIsFirstBarOfSession(idx))
                {
                    // First bar
                    if (closeValue > openValue)
                    {
                        point0.X = x;
                        point0.Y = open;
                        point1.X = x;
                        point1.Y = close;
                        TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width));
                        RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle);
                        thickLine = true;
                    }
                    else
                    {
                        point0.X = x;
                        point0.Y = open;
                        point1.X = x;
                        point1.Y = close;
                        TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width));
                        RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle);
                        thickLine = false;
                    }
                }
                else
                {
                    if (closeValue > openValue)
                    {
                        if (closeValue <= Math.Max(prevCloseValue, prevOpenValue))
                        {
                            // Maintain previous thickness
                            if (thickLine)
                            {
                                point0.X = x;
                                point0.Y = open + thickOffsetTop;
                                point1.X = x;
                                point1.Y = close - thickOffsetTop;
                                TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width));
                                RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle);
                                point0.X = startPosition;
                                point0.Y = open;
                                point1.X = x;
                                point1.Y = open;
                                TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width));
                                RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle);
                            }
                            else
                            {
                                point0.X = x;
                                point0.Y = open + thinOffsetTop;
                                point1.X = x;
                                point1.Y = close - thinOffsetTop;
                                TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width));
                                RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle);
                                point0.X = startPosition;
                                point0.Y = open;
                                point1.X = x;
                                point1.Y = open;
                                TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width));
                                RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle);
                            }
                        }
                        else if (closeValue > Math.Max(prevCloseValue, prevOpenValue))
                        {
                            double transitionPoint = Math.Max(prevCloseValue, prevOpenValue);

                            point0.X = x;
                            point0.Y = close - thickOffsetTop;
                            point1.X = x;
                            point1.Y = chartScale.GetYByValue(transitionPoint);
                            TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width));
                            RenderTarget.DrawLine(point0, point1, Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle);
                            point0.X = x;
                            point0.Y = chartScale.GetYByValue(transitionPoint);
                            point1.X = x;
                            point1.Y = open + (thickLine ? thickOffsetTop : thinOffsetTop);
                            TransformBrush(overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), new RectangleF(point0.X, point0.Y - (thickLine ? Stroke.Width : Stroke2.Width), barWidth, thickLine ? Stroke.Width : Stroke2.Width));
                            RenderTarget.DrawLine(point0, point1, overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), thickLine ? Stroke.Width : Stroke2.Width, thickLine ? Stroke.StrokeStyle : Stroke2.StrokeStyle);
                            point0.X = startPosition;
                            point0.Y = open;
                            point1.X = x;
                            point1.Y = open;
                            TransformBrush(overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), new RectangleF(point0.X, point0.Y - (thickLine ? Stroke.Width : Stroke2.Width), barWidth, thickLine ? Stroke.Width : Stroke2.Width));
                            RenderTarget.DrawLine(point0, point1, overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), thickLine ? Stroke.Width : Stroke2.Width, thickLine ? Stroke.StrokeStyle : Stroke2.StrokeStyle);

                            thickLine = true;
                        }
                    }
                    else
                    {
                        if (Math.Min(prevCloseValue, prevOpenValue) <= closeValue)
                        {
                            // Maintain previous thickness
                            if (thickLine)
                            {
                                point0.X = x;
                                point0.Y = open - thickOffsetTop;
                                point1.X = x;
                                point1.Y = close + thickOffsetTop;
                                TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width));
                                RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle);
                                point0.X = startPosition;
                                point0.Y = open;
                                point1.X = x;
                                point1.Y = open;
                                TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width));
                                RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle);
                            }
                            else
                            {
                                point0.X = x;
                                point0.Y = open - thinOffsetTop;
                                point1.X = x;
                                point1.Y = close + thinOffsetTop;
                                TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width));
                                RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle);
                                point0.X = startPosition;
                                point0.Y = open;
                                point1.X = x;
                                point1.Y = open;
                                TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width));
                                RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle);
                            }
                        }
                        else if (closeValue < Math.Min(prevCloseValue, prevOpenValue))
                        {
                            double transitionPoint = Math.Min(prevCloseValue, prevOpenValue);

                            point0.X = startPosition;
                            point0.Y = open;
                            point1.X = x;
                            point1.Y = open;
                            TransformBrush(overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), new RectangleF(point0.X, point0.Y - (thickLine ? Stroke.Width : Stroke2.Width), barWidth, thickLine ? Stroke.Width : Stroke2.Width));
                            RenderTarget.DrawLine(point0, point1, overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), thickLine ? Stroke.Width : Stroke2.Width, thickLine ? Stroke.StrokeStyle : Stroke2.StrokeStyle);
                            point0.X = x;
                            point0.Y = open - (thickLine ? thickOffsetTop : thinOffsetTop);
                            point1.X = x;
                            point1.Y = chartScale.GetYByValue(transitionPoint);
                            TransformBrush(overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), new RectangleF(point0.X, point0.Y - (thickLine ? Stroke.Width : Stroke2.Width), barWidth, thickLine ? Stroke.Width : Stroke2.Width));
                            RenderTarget.DrawLine(point0, point1, overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), thickLine ? Stroke.Width : Stroke2.Width, thickLine ? Stroke.StrokeStyle : Stroke2.StrokeStyle);
                            point0.X = x;
                            point0.Y = chartScale.GetYByValue(transitionPoint);
                            point1.X = x;
                            point1.Y = close + thinOffsetTop;
                            TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width));
                            RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle);

                            thickLine = false;
                        }
                    }
                }
            }
        }
예제 #18
0
		/// <summary>
		/// </summary>
		/// <param name="bars"></param>
		/// <param name="open"></param>
		/// <param name="high"></param>
		/// <param name="low"></param>
		/// <param name="close"></param>
		/// <param name="time"></param>
		/// <param name="volume"></param>
		/// <param name="isRealtime"></param>
		public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime)
		{
			offset = bars.Period.Value * bars.Instrument.MasterInstrument.TickSize;

			if (bars.Count < tmpCount && bars.Count > 0) // reset cache when bars are trimmed
			{
				renkoHigh	= bars.GetClose(bars.Count - 1) + offset;
				renkoLow	= bars.GetClose(bars.Count - 1) - offset;
			}

			if ((bars.Count == 0) || (bars.IsNewSession(time, isRealtime)))
			{
				if (bars.Count != 0)
				{
					// close out last bar in session and set open == close
					Bar lastBar = (Bar)bars.Get(bars.Count - 1);
					bars.RemoveLastBar(isRealtime);  // Note: bar is now just a local var and not in series!
					AddBar(bars, lastBar.Close, lastBar.Close, lastBar.Close, lastBar.Close, lastBar.Time, lastBar.Volume, isRealtime);
				}

				renkoHigh	= close + offset;
				renkoLow	= close - offset;
				AddBar(bars, close, close, close, close, time, volume, isRealtime);
				bars.LastPrice = close;
				return;
			}
			Bar bar = (Bar)bars.Get(bars.Count - 1);
			if (renkoHigh == 0 || renkoLow == 0)  //Not sure why, but happens
			{
				if (bars.Count == 1)
				{
					renkoHigh	= bar.Open + offset;
					renkoLow	= bar.Open - offset;
				}
				else if (bars.GetClose(bars.Count - 2) > bars.GetOpen(bars.Count - 2))
				{
					renkoHigh	= bars.GetClose(bars.Count - 2) + offset;
					renkoLow	= bars.GetClose(bars.Count - 2) - offset * 2;
				}
				else
				{
					renkoHigh	= bars.GetClose(bars.Count - 2) + offset * 2;
					renkoLow	= bars.GetClose(bars.Count - 2) - offset;
				}
			}
			if (bars.Instrument.MasterInstrument.Compare(close, renkoHigh) >= 0)
			{
				if (bars.Instrument.MasterInstrument.Compare(bar.Open, renkoHigh - offset) != 0
					|| bars.Instrument.MasterInstrument.Compare(bar.High, Math.Max(renkoHigh - offset, renkoHigh)) != 0
					|| bars.Instrument.MasterInstrument.Compare(bar.Low, Math.Min(renkoHigh - offset, renkoHigh)) != 0)
				{
					bars.RemoveLastBar(isRealtime);  // Note: bar is now just a local var and not in series!
					AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, renkoHigh), Math.Min(renkoHigh - offset, renkoHigh), renkoHigh, time, bar.Volume + volume, isRealtime);
				}
				else
					UpdateBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, renkoHigh), Math.Min(renkoHigh - offset, renkoHigh), renkoHigh, time, volume, isRealtime);

				renkoLow	= renkoHigh - 2.0 * offset;
				renkoHigh	= renkoHigh + offset;

				while (bars.Instrument.MasterInstrument.Compare(close, renkoHigh) >= 0)	// add empty bars to fill gap
				{
					AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, renkoHigh), Math.Min(renkoHigh - offset, renkoHigh), renkoHigh, time, 1, isRealtime);
					renkoLow	= renkoHigh - 2.0 * offset;
					renkoHigh	= renkoHigh + offset;
				}

				// add final partial bar
				AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, close), Math.Min(renkoHigh - offset, close), close, time, 1, isRealtime);
			}
			else
				if (bars.Instrument.MasterInstrument.Compare(close, renkoLow) <= 0)
				{
					if (bars.Instrument.MasterInstrument.Compare(bar.Open, renkoLow + offset) != 0
						|| bars.Instrument.MasterInstrument.Compare(bar.High, Math.Max(renkoLow + offset, renkoLow)) != 0
						|| bars.Instrument.MasterInstrument.Compare(bar.Low, Math.Min(renkoLow + offset, renkoLow)) != 0)
					{
						bars.RemoveLastBar(isRealtime);  // Note: bar is now just a local var and not in series!
						AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, time, bar.Volume + volume, isRealtime);
					}
					else
						UpdateBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, time, volume, isRealtime);

					renkoHigh	= renkoLow + 2.0 * offset;
					renkoLow	= renkoLow - offset;

					while (bars.Instrument.MasterInstrument.Compare(close, renkoLow) <= 0)	// add empty bars to fill gap
					{
						AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, time, 1, isRealtime);
						renkoHigh	= renkoLow + 2.0 * offset;
						renkoLow	= renkoLow - offset;
					}

					// add final partial bar
					AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, close), Math.Min(renkoLow + offset, close), close, time, 1, isRealtime);
				}
				else    // Note: open does not really change
					UpdateBar(bars, close, close, close, close, time, volume, isRealtime);

			bars.LastPrice	= close;
			tmpCount		= bars.Count;
		}
예제 #19
0
        public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime)
        {
            //	******************* ADDED FROM RENKO CODE TO SOLVE MEMORY LEAK	****************************
            // brick size is the trendOffset (Value) + openOffset (BasePeriodValue)
            offset = (bars.Period.Value + bars.Period.BasePeriodValue) * bars.Instrument.MasterInstrument.TickSize;

            if (bars.Count < tmpCount && bars.Count > 0)             // reset cache when bars are trimmed
            {
                barMax = bars.GetClose(bars.Count - 1) + offset;
                barMin = bars.GetClose(bars.Count - 1) - offset;
            }
            //	 ********************************************************************************************


            //### First Bar
            if ((bars.Count == 0) || bars.IsNewSession(time, isRealtime))
            {
                tickSize = bars.Instrument.MasterInstrument.TickSize;

                //### Parse Long Param Specification
                if (bars.Period.Value >= 1000000)
                {
                    int d; string str = bars.Period.Value.ToString("000000000");
                    d = 0; Int32.TryParse(str.Substring(0, 3), out d); bars.Period.Value = d;
                    d = 0; Int32.TryParse(str.Substring(3, 3), out d); bars.Period.Value2 = d;
                    d = 0; Int32.TryParse(str.Substring(6, 3), out d); bars.Period.BasePeriodValue = d;
                }

                //****** ADDED FROM RENKO *****************************************************************
                if (bars.Count != 0)
                {
                    // close out last bar in session and set open == close
                    Bar lastBar = (Bar)bars.Get(bars.Count - 1);
                    bars.RemoveLastBar();                      // Note: bar is now just a local var and not in series!
                    AddBar(bars, lastBar.Close, lastBar.High, lastBar.Low, lastBar.Close, lastBar.Time, lastBar.Volume, isRealtime);
                }

                //****************************************************************************************


                trendOffset    = bars.Period.Value * bars.Instrument.MasterInstrument.TickSize;
                reversalOffset = bars.Period.Value2 * bars.Instrument.MasterInstrument.TickSize;
                //bars.Period.BasePeriodValue = bars.Period.Value;	//### Remove to customize OpenOffset
                openOffset = Math.Ceiling((double)bars.Period.BasePeriodValue * 1) * bars.Instrument.MasterInstrument.TickSize;

                barOpen = close;
                barMax  = barOpen + (trendOffset * barDirection);
                barMin  = barOpen - (trendOffset * barDirection);


                AddBar(bars, barOpen, barOpen, barOpen, barOpen, time, volume, isRealtime);
            }
            //### Subsequent Bars
            else
            {
                Data.Bar bar = (Bar)bars.Get(bars.Count - 1);
                // *************ADDED FROM RENKO CODE (to deal with '0' values at Market Replay) ************
                if (barMax == 0 || barMin == 0)                  //Not sure why, but happens
                {
                    // trendOffset was also '0', so need to reinitialize
                    trendOffset    = bars.Period.Value * bars.Instrument.MasterInstrument.TickSize;
                    reversalOffset = bars.Period.Value2 * bars.Instrument.MasterInstrument.TickSize;
                    openOffset     = Math.Ceiling((double)bars.Period.BasePeriodValue * 1) * bars.Instrument.MasterInstrument.TickSize;

                    if (bars.Count == 1)
                    {
                        barMax = bar.Open + trendOffset;
                        barMin = bar.Open - trendOffset;
                    }
                    else if (bars.GetClose(bars.Count - 2) > bars.GetOpen(bars.Count - 2))
                    {
                        barMax = bars.GetClose(bars.Count - 2) + trendOffset;
                        barMin = bars.GetClose(bars.Count - 2) - trendOffset * 2;
                    }
                    else
                    {
                        barMax = bars.GetClose(bars.Count - 2) + trendOffset * 2;
                        barMin = bars.GetClose(bars.Count - 2) - trendOffset;
                    }
                }

                // ************************************************************************************************

                maxExceeded = bars.Instrument.MasterInstrument.Compare(close, barMax) > 0 ? true : false;
                minExceeded = bars.Instrument.MasterInstrument.Compare(close, barMin) < 0 ? true : false;

                //### Defined Range Exceeded?
                if (maxExceeded || minExceeded)
                {
                    double thisClose = maxExceeded ? Math.Min(close, barMax) : minExceeded?Math.Max(close, barMin) : close;  // thisClose is the minimum of BarMax and close (maxExceeded)


                    barDirection = maxExceeded ? 1 : minExceeded ? -1 : 0;
                    fakeOpen     = thisClose - (openOffset * barDirection);     //### Fake Open is halfway down the bar

                    //### Close Current Bar
                    UpdateBar(bars, bar.Open, (maxExceeded ? thisClose : bar.High), (minExceeded ? thisClose : bar.Low), thisClose, time, volume, isRealtime);

                    //### Add New Bar
                    barOpen = close;
                    barMax  = thisClose + ((barDirection > 0 ? trendOffset : reversalOffset));
                    barMin  = thisClose - ((barDirection > 0 ? reversalOffset : trendOffset));



                    AddBar(bars, fakeOpen, (maxExceeded ? thisClose : fakeOpen), (minExceeded ? thisClose : fakeOpen), thisClose, time, volume, isRealtime);
                }
                //### Current Bar Still Developing
                else
                {
                    UpdateBar(bars, bar.Open, (close > bar.High ? close : bar.High), (close < bar.Low ? close : bar.Low), close, time, volume, isRealtime);
                }
            }

            bars.LastPrice = close;

            tmpCount = bars.Count;                            // ADDED FROM RENKO CODE
        }
예제 #20
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="bars"></param>
		/// <param name="open"></param>
		/// <param name="high"></param>
		/// <param name="low"></param>
		/// <param name="close"></param>
		/// <param name="time"></param>
		/// <param name="volume"></param>
		/// <param name="isRealtime"></param>
		public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime)
		{
			if (bars.Count == 0 && tmpTime != Cbi.Globals.MinDate) // reset caching when live request trimmed existing bars
				tmpTime = Cbi.Globals.MinDate;

			bool endOfBar = true;
			if (tmpTime == Cbi.Globals.MinDate)
			{
				tmpTime			= time;
				tmpDayCount		= 1;
				tmpTickCount	= 1;
			}
			else if (bars.Count < tmpCount && bars.Count == 0) // reset cache when bars are trimmed
			{
				tmpTime			= Cbi.Globals.MinDate;
				tmpVolume		= 0;
				tmpDayCount		= 0;
				tmpTickCount	= 0;
			}
			else if (bars.Count < tmpCount && bars.Count > 0) // reset cache when bars are trimmed
			{
				tmpTime			= bars.GetTime(bars.Count - 1); 
				tmpVolume		= bars.GetVolume(bars.Count - 1);
				tmpTickCount	= bars.TickCount;
				tmpDayCount		= bars.DayCount;
			}

			switch (bars.Period.BasePeriodType)
			{
				case PeriodType.Day:
					{
						if (bars.Count == 0 || (bars.Count > 0 && (bars.TimeLastBar.Month < time.Month || bars.TimeLastBar.Year < time.Year)))
						{
							tmpTime			= time.Date;
							bars.LastPrice	= close;
							newSession		= true;
						}
						else
						{
							tmpTime			= time.Date;
							tmpVolume		+= volume;
							bars.LastPrice	= close;
							tmpDayCount++;

							if (tmpDayCount < bars.Period.BasePeriodValue || (bars.Count > 0 && bars.TimeLastBar.Date == time.Date))
								endOfBar = false;
						}
						break;
					}
				case PeriodType.Minute:
					{
						if (bars.Count == 0 || bars.IsNewSession(time, isRealtime))
						{
							tmpTime		= TimeToBarTimeMinute(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue, isRealtime);
							newSession	= true;
							tmpVolume	= 0;
						}
						else
						{
							if (isRealtime && time < bars.TimeLastBar || !isRealtime && time <= bars.TimeLastBar)
							{
								tmpTime		= bars.TimeLastBar;
								endOfBar	= false;
							}
							else
								tmpTime		= TimeToBarTimeMinute(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue, isRealtime);

							tmpVolume		+= volume;
						}
						break;
					}
				case PeriodType.Month:
					{
						if (tmpTime == Cbi.Globals.MinDate)
						{
							tmpTime		= TimeToBarTimeMonth(time, bars.Period.BasePeriodValue);

							if (bars.Count == 0)
								break;

							endOfBar = false;
						}
						else if ((time.Month <= tmpTime.Month && time.Year == tmpTime.Year) || time.Year < tmpTime.Year)
						{
							tmpVolume		+= volume;
							bars.LastPrice	= close;
							endOfBar		= false;
						}
						break;
					}
				case PeriodType.Second:
					{
						if (bars.IsNewSession(time, isRealtime))
						{
							tmpTime = TimeToBarTimeSecond(bars, time, new DateTime(bars.Session.NextBeginTime.Year, bars.Session.NextBeginTime.Month, bars.Session.NextBeginTime.Day, bars.Session.NextBeginTime.Hour, bars.Session.NextBeginTime.Minute, 0), bars.Period.BasePeriodValue);

							if (bars.Count == 0)
								break;

							endOfBar	= false;
							newSession	= true;
						}
						else if (time <= tmpTime)
						{
							tmpVolume		+= volume;
							bars.LastPrice	= close;
							endOfBar		= false;
						}
						else
							tmpTime = TimeToBarTimeSecond(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue);
						break;
					}
				case PeriodType.Tick:
					{
						if (bars.IsNewSession(time, isRealtime))
						{
							newSession = true;
							tmpTime = time;
							tmpTickCount = 1;

							if (bars.Count == 0)
								break;

							endOfBar = false;
						}
						else if (bars.Period.BasePeriodValue > 1 && tmpTickCount < bars.Period.BasePeriodValue)
						{
							tmpTime			= time;
							tmpVolume		+= volume;
							tmpTickCount++;
							bars.LastPrice	= close;
							endOfBar		= false;
						}
						else
							tmpTime = time; // there can't be a situation when new ticks go into old bar, this would mean peeking into future. Fixed in NT7B14 20100416 CH
						break;
					}
				case PeriodType.Volume:
					{
						if (bars.IsNewSession(time, isRealtime))
							newSession = true;
						else if (bars.Count == 0 && volume > 0)
							break;
						else
						{
							tmpVolume += volume;
							if (tmpVolume < bars.Period.BasePeriodValue)
							{
								bars.LastPrice = close;
								endOfBar = false;
							}
							else if (tmpVolume == 0)
								endOfBar = false;
						}

						tmpTime = time; // there can't be a situation when new ticks go into old bar, this would mean peeking into future. Fixed in NT7B14 20100416 CH

						break;
					}
				case PeriodType.Week:
					{
						if (tmpTime == Cbi.Globals.MinDate)
						{
							tmpTime			= TimeToBarTimeWeek(time.Date, tmpTime.Date, bars.Period.BasePeriodValue);

							if (bars.Count == 0)
								break;

							endOfBar = false;
						}
						else if (time.Date <= tmpTime.Date)
						{
							tmpVolume		+= volume;
							bars.LastPrice	= close;
							endOfBar		= false;
						}
						break;
					}
				case PeriodType.Year:
					{
						if (tmpTime == Cbi.Globals.MinDate)
						{
							tmpTime			= TimeToBarTimeYear(time, bars.Period.Value);

							if (bars.Count == 0)
								break;

							endOfBar = false;
						}
						else if (time.Year <= tmpTime.Year)
						{
							tmpVolume		+= volume;
							bars.LastPrice	= close;
							endOfBar		= false;
						}
						break;
					}
				default:
					break;
			}

			if (bars.Count == 0 || (newSession && IsIntraday))
			{
				AddBar(bars, open, close, close, close, tmpTime, volume, isRealtime);
				upTrend				= (open < close);
				newSessionIdx		= bars.Count - 1;
				newSession			= false;
				firstBarOfSession	= true;
				anchorPrice			= close;
				switchPrice			= open;
			}
			else if (firstBarOfSession && endOfBar == false)
			{
				double prevOpen		= bars.GetOpen(bars.Count - 1);
				bars.RemoveLastBar(isRealtime);
				AddBar(bars, prevOpen, close, close, close, tmpTime, tmpVolume, isRealtime);
				upTrend				= (prevOpen < close);
				anchorPrice			= close;
			}
			else
			{
				int		breakCount		= bars.Period.Value;
				Bar		bar				= (Bar)bars.Get(bars.Count - 1);
				double	breakMax		= double.MinValue;
				double	breakMin		= double.MaxValue;

				if (firstBarOfSession)
				{
					AddBar(bars, anchorPrice, close, close, close, tmpTime, volume, isRealtime);
					firstBarOfSession	= false;
					tmpVolume			= volume;
					tmpTime				= Cbi.Globals.MinDate;
					return;
				}

				if (bars.Count - newSessionIdx - 1 < breakCount)
					breakCount = bars.Count - (newSessionIdx + 1);

				for (int k = 1; k <= breakCount; k++)
				{
					Bar tmp			= (Bar)bars.Get(bars.Count - k - 1);
					breakMax		= Math.Max(breakMax, tmp.Open);
					breakMax		= Math.Max(breakMax, tmp.Close);
					breakMin		= Math.Min(breakMin, tmp.Open);
					breakMin		= Math.Min(breakMin, tmp.Close);
				}

				bars.LastPrice = close;

				if (upTrend)
					if (endOfBar)
					{
						bool adding = false;
						if (bars.Instrument.MasterInstrument.Compare(bar.Close, anchorPrice) > 0)
						{
							anchorPrice = bar.Close;
							switchPrice = bar.Open;
							tmpVolume = volume;
							adding = true;
						}
						else
							if (bars.Instrument.MasterInstrument.Compare(breakMin, bar.Close) > 0)
							{
								anchorPrice = bar.Close;
								switchPrice = bar.Open;
								tmpVolume = volume;
								upTrend = false;
								adding = true;
							}

						if (adding)
						{
							double tmpOpen = upTrend ? Math.Min(Math.Max(switchPrice, close), anchorPrice) : Math.Max(Math.Min(switchPrice, close), anchorPrice);
							AddBar(bars, tmpOpen, close, close, close, tmpTime, volume, isRealtime);
						}
						else
						{
							bars.RemoveLastBar(isRealtime);
							double tmpOpen = Math.Min(Math.Max(switchPrice, close), anchorPrice);
							AddBar(bars, tmpOpen, close, close, close, tmpTime, tmpVolume, isRealtime);
						}
					}
					else
					{
						bars.RemoveLastBar(isRealtime);
						double tmpOpen = Math.Min(Math.Max(switchPrice, close), anchorPrice);
						AddBar(bars, tmpOpen, close, close, close, tmpTime, tmpVolume, isRealtime);
					}
				else
					if (endOfBar)
					{
						bool adding = false;
						if (bars.Instrument.MasterInstrument.Compare(bar.Close, anchorPrice) < 0)
						{
							anchorPrice		= bar.Close;
							switchPrice		= bar.Open;
							tmpVolume		= volume;
							adding			= true;
						}
						else
							if (bars.Instrument.MasterInstrument.Compare(breakMax, bar.Close) < 0)
							{
								anchorPrice		= bar.Close;
								switchPrice		= bar.Open;
								tmpVolume		= volume;
								upTrend			= true;
								adding			= true;
							}

						if (adding)
						{
							double tmpOpen = upTrend ? Math.Min(Math.Max(switchPrice, close), anchorPrice) : Math.Max(Math.Min(switchPrice, close), anchorPrice);
							AddBar(bars, tmpOpen, close, close, close, tmpTime, volume, isRealtime);
						}
						else
						{
							bars.RemoveLastBar(isRealtime);
							double tmpOpen = Math.Max(Math.Min(switchPrice, close), anchorPrice);
							AddBar(bars, tmpOpen, close, close, close, tmpTime, tmpVolume, isRealtime);
						}
					}
					else
					{
						bars.RemoveLastBar(isRealtime);
						double tmpOpen = Math.Max(Math.Min(switchPrice, close), anchorPrice);
						AddBar(bars, tmpOpen, close, close, close, tmpTime, tmpVolume, isRealtime);
					}
			}

			if (endOfBar)
				tmpTime = Cbi.Globals.MinDate;

			tmpCount = bars.Count;
		}
예제 #21
0
        public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime)
        {
            #region Reset cache
            if (bars.Count == 0 && tmpTime != Cbi.Globals.MinDate)                     // reset caching when live request trimmed existing bars
            {
                tmpTime = Cbi.Globals.MinDate;
            }

            bool endOfBar = true;
            if (tmpTime == Cbi.Globals.MinDate)
            {
                tmpTime      = time;
                tmpDayCount  = 1;
                tmpTickCount = 1;
            }
            else if (bars.Count < tmpCount && bars.Count == 0)                     // reset cache when bars are trimmed
            {
                tmpTime      = Cbi.Globals.MinDate;
                tmpVolume    = 0;
                tmpDayCount  = 0;
                tmpTickCount = 0;
            }
            else if (bars.Count < tmpCount && bars.Count > 0)                     // reset cache when bars are trimmed
            {
                tmpTime      = bars.GetTime(bars.Count - 1);
                tmpVolume    = bars.GetVolume(bars.Count - 1);
                tmpTickCount = bars.TickCount;
                tmpDayCount  = bars.DayCount;
            }
            #endregion

            #region Switch Periods
            switch (bars.Period.BasePeriodType)
            {
                #region tick
            case PeriodType.Tick:
            {
                if (bars.IsNewSession(time, isRealtime))
                {
                    newSession   = true;
                    tmpTime      = time;
                    tmpTickCount = 1;

                    if (bars.Count == 0)
                    {
                        break;
                    }

                    endOfBar = false;
                }
                else
                {
                    if (bars.Period.BasePeriodValue > 1 && tmpTickCount < bars.Period.BasePeriodValue)
                    {
                        tmpTime    = time;
                        tmpVolume += volume;
                        tmpTickCount++;
                        bars.LastPrice = close;
                        endOfBar       = false;
                    }
                    else
                    {
                        tmpTime = time;                                 // there can't be a situation when new ticks go into old bar, this would mean peeking into future. Fixed in NT7B14 20100416 CH
                    }
                }
                break;
            }

                #endregion
                #region Volume
            case PeriodType.Volume:
            {
                if (bars.IsNewSession(time, isRealtime))
                {
                    newSession = true;
                }
                else if (bars.Count == 0 && volume > 0)
                {
                    break;
                }
                else
                {
                    tmpVolume += volume;
                    if (tmpVolume < bars.Period.BasePeriodValue)
                    {
                        bars.LastPrice = close;
                        endOfBar       = false;
                    }
                    else if (tmpVolume == 0)
                    {
                        endOfBar = false;
                    }
                }

                tmpTime = time;                         // there can't be a situation when new ticks go into old bar, this would mean peeking into future. Fixed in NT7B14 20100416 CH

                break;
            }

                #endregion
                #region Second
            case PeriodType.Second:
            {
                if (bars.IsNewSession(time, isRealtime))
                {
                    tmpTime = TimeToBarTimeSecond(bars, time, new DateTime(bars.Session.NextBeginTime.Year, bars.Session.NextBeginTime.Month, bars.Session.NextBeginTime.Day, bars.Session.NextBeginTime.Hour, bars.Session.NextBeginTime.Minute, 0), bars.Period.BasePeriodValue);

                    if (bars.Count == 0)
                    {
                        break;
                    }

                    endOfBar   = false;
                    newSession = true;
                }
                else
                {
                    if (time <= tmpTime)
                    {
                        tmpVolume     += volume;
                        bars.LastPrice = close;
                        endOfBar       = false;
                    }
                    else
                    {
                        tmpTime = TimeToBarTimeSecond(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue);
                    }
                }
                break;
            }

                #endregion
                #region Day
            case PeriodType.Day:
            {
                if (bars.Count == 0 || (bars.Count > 0 && (bars.TimeLastBar.Month < time.Month || bars.TimeLastBar.Year < time.Year)))
                {
                    tmpTime        = time.Date;
                    bars.LastPrice = close;
                    newSession     = true;
                }
                else
                {
                    tmpTime        = time.Date;
                    tmpVolume     += volume;
                    bars.LastPrice = close;
                    tmpDayCount++;

                    if (tmpDayCount < bars.Period.BasePeriodValue || (bars.Count > 0 && bars.TimeLastBar.Date == time.Date))
                    {
                        endOfBar = false;
                    }
                }
                break;
            }

                #endregion
                #region Minute
            case PeriodType.Minute:
            {
                if (bars.Count == 0 || bars.IsNewSession(time, isRealtime))
                {
                    tmpTime    = TimeToBarTimeMinute(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue, isRealtime);
                    newSession = true;
                    tmpVolume  = 0;
                }
                else
                {
                    if (isRealtime && time < bars.TimeLastBar || !isRealtime && time <= bars.TimeLastBar)
                    {
                        tmpTime  = bars.TimeLastBar;
                        endOfBar = false;
                    }
                    else
                    {
                        tmpTime = TimeToBarTimeMinute(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue, isRealtime);
                    }

                    tmpVolume += volume;
                }
                break;
            }

                #endregion
                #region Week
            case PeriodType.Week:
            {
                if (tmpTime == Cbi.Globals.MinDate)
                {
                    tmpTime = TimeToBarTimeWeek(time.Date, tmpTime.Date, bars.Period.BasePeriodValue);

                    if (bars.Count == 0)
                    {
                        break;
                    }

                    endOfBar = false;
                }
                else
                {
                    if (time.Date <= tmpTime.Date)
                    {
                        tmpVolume     += volume;
                        bars.LastPrice = close;
                        endOfBar       = false;
                    }
                }
                break;
            }

                #endregion
                #region Month
            case PeriodType.Month:
            {
                if (tmpTime == Cbi.Globals.MinDate)
                {
                    tmpTime = TimeToBarTimeMonth(time, bars.Period.BasePeriodValue);

                    if (bars.Count == 0)
                    {
                        break;
                    }

                    endOfBar = false;
                }
                else
                {
                    if ((time.Month <= tmpTime.Month && time.Year == tmpTime.Year) || time.Year < tmpTime.Year)
                    {
                        tmpVolume     += volume;
                        bars.LastPrice = close;
                        endOfBar       = false;
                    }
                }
                break;
            }

                #endregion
                #region Year
            case PeriodType.Year:
            {
                if (tmpTime == Cbi.Globals.MinDate)
                {
                    tmpTime = TimeToBarTimeYear(time, bars.Period.Value);

                    if (bars.Count == 0)
                    {
                        break;
                    }

                    endOfBar = false;
                }
                else
                {
                    if (time.Year <= tmpTime.Year)
                    {
                        tmpVolume     += volume;
                        bars.LastPrice = close;
                        endOfBar       = false;
                    }
                }
                break;
            }

                #endregion
                #region Default
            default:
                break;
                #endregion
            }
            #endregion

            #region Add bars
            if (bars.Count == 0 || (newSession && IsIntraday))              // Very first bar setup.
            {
                #region First bar
                AddBar(bars, open, close, close, close, tmpTime, volume, isRealtime);
                upTrend           = (open < close);
                newSessionIdx     = bars.Count - 1;
                newSession        = false;
                firstBarOfSession = true;
                anchorPrice       = close;
                switchPrice       = open;
                tmpHigh           = close;
                tmpLow            = close;
                #endregion
            }
            else if (firstBarOfSession && endOfBar == false)
            {
                #region Start of subsiquent bars
                double prevOpen = bars.GetOpen(bars.Count - 1);
                bars.RemoveLastBar(isRealtime);
                AddBar(bars, prevOpen, close, close, close, tmpTime, tmpVolume, isRealtime);
                upTrend     = (prevOpen < close);
                anchorPrice = close;
                #endregion
            }
            else
            {
                int    breakCount = bars.Period.Value;
                Bar    bar        = (Bar)bars.Get(bars.Count - 1);
                double breakMax   = double.MinValue;
                double breakMin   = double.MaxValue;

                if (firstBarOfSession)
                {
                    AddBar(bars, anchorPrice, close, close, close, tmpTime, volume, isRealtime);
                    firstBarOfSession = false;
                    tmpVolume         = volume;
                    tmpTime           = Cbi.Globals.MinDate;
                    return;
                }

                if (bars.Count - newSessionIdx - 1 < breakCount)
                {
                    breakCount = bars.Count - (newSessionIdx + 1);
                }

                for (int k = 1; k <= breakCount; k++)
                {
                    Bar tmp = (Bar)bars.Get(bars.Count - k - 1);
                    breakMax = Math.Max(breakMax, tmp.Open);
                    breakMax = Math.Max(breakMax, tmp.Close);
                    breakMin = Math.Min(breakMin, tmp.Open);
                    breakMin = Math.Min(breakMin, tmp.Close);
                }

                bars.LastPrice = close;

                if (upTrend)
                {
                    #region Up trend
                    if (endOfBar)
                    {
                        bool adding = false;
                        if (bars.Instrument.MasterInstrument.Compare(bar.Close, anchorPrice) > 0)
                        {
                            anchorPrice = bar.Close;
                            switchPrice = bar.Open;
                            tmpVolume   = volume;
                            adding      = true;
                            tmpHigh     = bar.Close;
                            tmpLow      = bar.Close;
                        }
                        else if (bars.Instrument.MasterInstrument.Compare(breakMin, bar.Close) > 0)
                        {
                            anchorPrice = bar.Close;
                            switchPrice = bar.Open;
                            tmpVolume   = volume;
                            upTrend     = false;
                            adding      = true;
                            tmpHigh     = bar.Close;
                            tmpLow      = bar.Close;
                        }

                        if (adding)
                        {
                            double tmpOpen = upTrend ? Math.Min(Math.Max(switchPrice, close), anchorPrice) : Math.Max(Math.Min(switchPrice, close), anchorPrice);
                            tmpHigh = Math.Max(tmpHigh, close);
                            tmpLow  = Math.Min(tmpLow, close);
                            AddBar(bars, tmpOpen, tmpHigh, tmpLow, close, tmpTime, volume, isRealtime);
                        }
                        else
                        {
                            bars.RemoveLastBar(isRealtime);
                            double tmpOpen = Math.Min(Math.Max(switchPrice, close), anchorPrice);
                            tmpHigh = Math.Max(tmpHigh, close);
                            tmpLow  = Math.Min(tmpLow, close);
                            AddBar(bars, tmpOpen, tmpHigh, tmpLow, close, tmpTime, tmpVolume, isRealtime);
                        }
                    }
                    else
                    {
                        bars.RemoveLastBar(isRealtime);
                        double tmpOpen = Math.Min(Math.Max(switchPrice, close), anchorPrice);
                        tmpHigh = Math.Max(tmpHigh, close);
                        tmpLow  = Math.Min(tmpLow, close);
                        AddBar(bars, tmpOpen, tmpHigh, tmpLow, close, tmpTime, tmpVolume, isRealtime);
                    }
                    #endregion
                }
                else
                {
                    #region Down trend
                    if (endOfBar)
                    {
                        bool adding = false;
                        if (bars.Instrument.MasterInstrument.Compare(bar.Close, anchorPrice) < 0)
                        {
                            anchorPrice = bar.Close;
                            switchPrice = bar.Open;
                            tmpVolume   = volume;
                            adding      = true;
                            tmpHigh     = bar.Close;
                            tmpLow      = bar.Close;
                        }
                        else if (bars.Instrument.MasterInstrument.Compare(breakMax, bar.Close) < 0)
                        {
                            anchorPrice = bar.Close;
                            switchPrice = bar.Open;
                            tmpVolume   = volume;
                            upTrend     = true;
                            adding      = true;
                            tmpHigh     = bar.Close;
                            tmpLow      = bar.Close;
                        }

                        if (adding)
                        {
                            double tmpOpen = upTrend ? Math.Min(Math.Max(switchPrice, close), anchorPrice) : Math.Max(Math.Min(switchPrice, close), anchorPrice);
                            tmpHigh = Math.Max(tmpHigh, close);
                            tmpLow  = Math.Min(tmpLow, close);
                            AddBar(bars, tmpOpen, tmpHigh, tmpLow, close, tmpTime, volume, isRealtime);
                        }
                        else
                        {
                            bars.RemoveLastBar(isRealtime);
                            double tmpOpen = Math.Max(Math.Min(switchPrice, close), anchorPrice);
                            tmpHigh = Math.Max(tmpHigh, close);
                            tmpLow  = Math.Min(tmpLow, close);
                            AddBar(bars, tmpOpen, tmpHigh, tmpLow, close, tmpTime, tmpVolume, isRealtime);
                        }
                    }
                    else
                    {
                        bars.RemoveLastBar(isRealtime);
                        double tmpOpen = Math.Max(Math.Min(switchPrice, close), anchorPrice);
                        tmpHigh = Math.Max(tmpHigh, close);
                        tmpLow  = Math.Min(tmpLow, close);
                        AddBar(bars, tmpOpen, tmpHigh, tmpLow, close, tmpTime, tmpVolume, isRealtime);
                    }
                    #endregion
                }
            }
            #endregion

            if (endOfBar)
            {
                tmpTime = Cbi.Globals.MinDate;
            }

            tmpCount = bars.Count;
        }
예제 #22
0
        protected override void OnBarUpdate()
        {
            /* When working with multiple bar series objects it is important to understand the sequential order in which the
             * OnBarUpdate() method is triggered. The bars will always run with the primary first followed by the secondary and
             * so on.
             *
             * Important: Primary bars will always execute before the secondary bar series.
             * If a bar is timestamped as 12:00PM on the 5min bar series, the call order between the equally timestamped 12:00PM
             * bar on the 1min bar series is like this:
             *  12:00PM 5min
             *  12:00PM 1min
             *  12:01PM 1min
             *  12:02PM 1min
             *  12:03PM 1min
             *  12:04PM 1min
             *  12:05PM 5min
             *  12:05PM 1min
             *
             * When the OnBarUpdate() is called from the primary bar series (2000 ticks series in this example), do the following */
            if (BarsInProgress == 0)
            {
                if (CurrentBar < BarsRequiredToTrade)
                {
                    return;
                }

                //Print("Current Bar time=" + Bars.GetTime(CurrentBar).ToString("HHmmss"));

                // if the bar elapsed time span across 12 mid night
                DateTime t1 = Bars.GetTime(CurrentBar - 1);
                DateTime t2 = Bars.GetTime(CurrentBar);
                if (TimeSpan.Compare(t1.TimeOfDay, t2.TimeOfDay) > 0)
                {
                    Print("EOD Session");
                    HandleEOD();

                    string resetString = "-1";
                    byte[] resetMsg    = Encoding.UTF8.GetBytes(resetString);

                    // Send reset string of "-1" to the server
                    int resetSent = sender.Send(resetMsg);
                    lineNo = 0;

                    //reset global flags
                    currPos             = Position.posFlat;
                    profitChasingFlag   = false;
                    stopLossEncountered = false;
                    return;
                }

                // prior Stop-Loss observed, construct the lineNo with special code before sending msg to the server - so that the server will flatten the position
                if (stopLossEncountered)
                {
                    lineNo += 10000;
                }

                // construct the string buffer to be sent to DLNN
                string bufString = lineNo.ToString() + ',' +
                                   Bars.GetTime(CurrentBar - 1).ToString("HHmmss") + ',' + Bars.GetTime(CurrentBar).ToString("HHmmss") + ',' +
                                   Bars.GetOpen(CurrentBar).ToString() + ',' + Bars.GetClose(CurrentBar).ToString() + ',' +
                                   Bars.GetHigh(CurrentBar).ToString() + ',' + Bars.GetLow(CurrentBar).ToString() + ',' +
                                   Bars.GetVolume(CurrentBar).ToString() + ',' +
                                   SMA(9)[0].ToString() + ',' + SMA(20)[0].ToString() + ',' + SMA(50)[0].ToString() + ',' +
                                   MACD(12, 26, 9).Diff[0].ToString() + ',' + RSI(14, 3)[0].ToString() + ',' +
                                   Bollinger(2, 20).Lower[0].ToString() + ',' + Bollinger(2, 20).Upper[0].ToString() + ',' +
                                   CCI(20)[0].ToString() + ',' +
                                   Bars.GetHigh(CurrentBar).ToString() + ',' + Bars.GetLow(CurrentBar).ToString() + ',' +
                                   Momentum(20)[0].ToString() + ',' +
                                   DM(14).DiPlus[0].ToString() + ',' + DM(14).DiMinus[0].ToString() + ',' +
                                   VROC(25, 3)[0].ToString() + ',' +
                                   '0' + ',' + '0' + ',' + '0' + ',' + '0' + ',' + '0' + ',' +
                                   '0' + ',' + '0' + ',' + '0' + ',' + '0' + ',' + '0';

                //Print("CurrentBar = " + CurrentBar + ": " + "bufString = " + bufString);

                byte[] msg = Encoding.UTF8.GetBytes(bufString);

                // Send the data through the socket.
                int bytesSent = sender.Send(msg);

                // Receive the response from the remote device.
                int bytesRec = sender.Receive(bytes);

                // prior Stop-Loss observed, hence ignore the returned signal from server and move on to the next bar, reset lineNo to next counter and reset stopLossEncountered flag
                if (stopLossEncountered)
                {
                    lineNo -= 10000;
                    lineNo++;
                    stopLossEncountered = false;

                    //svrSignal = ExtractResponse(System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length));
                    svrSignal = System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length).Split(',')[1];
                    Print(Bars.GetTime(CurrentBar).ToString("yyyy-MM-ddTHH:mm:ss.ffffffK") + " Ignore Post STOP-LOSS Server response= <" + svrSignal + "> Current Bar: Open=" + Bars.GetOpen(CurrentBar) + " Close=" + Bars.GetClose(CurrentBar) + " High=" + Bars.GetHigh(CurrentBar) + " Low=" + Bars.GetLow(CurrentBar));

                    return;
                }

                //svrSignal = ExtractResponse(System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length));
                svrSignal = System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length).Split(',')[1];
                Print(Bars.GetTime(CurrentBar).ToString("yyyy-MM-ddTHH:mm:ss.ffffffK") + " Server response= <" + svrSignal + "> Current Bar: Open=" + Bars.GetOpen(CurrentBar) + " Close=" + Bars.GetClose(CurrentBar) + " High=" + Bars.GetHigh(CurrentBar) + " Low=" + Bars.GetLow(CurrentBar));
                //Print(Bars.GetTime(CurrentBar).ToString("yyyy-MM-ddTHH:mm:ss.ffffffK") + " Server response= <" + svrSignal + ">");

                // Return signal from DLNN is not we expected, close outstanding position and restart
                if (bytesRec == -1)
                {
                    lineNo = 0;
                    // TODO: close current position?
                }
                else
                {
                    lineNo++;
                }

                // Start processing signal after 8th signal and beyond, otherwise ignore
                if (lineNo >= 8)
                {
                    ExecuteAITrade(svrSignal);

                    // if position is flat, no need to do anything
                    if (currPos == Position.posFlat)
                    {
                        return;
                    }

                    // handle stop loss or profit chasing if there is existing position and order action is either SellShort or Buy
                    if (entryOrder != null && (entryOrder.OrderAction == OrderAction.Buy || entryOrder.OrderAction == OrderAction.SellShort) && (entryOrder.OrderState == OrderState.Filled || entryOrder.OrderState == OrderState.PartFilled))
                    {
                        // if Close[0] violates soft deck, if YES handle stop loss accordingly
                        if (ViolateSoftDeck())
                        {
                            HandleSoftDeck(svrSignal);
                        }

                        // if profitChasingFlag is TRUE or TouchedProfitChasing then handle profit chasing
                        if ((profitChasingFlag || TouchedProfitChasing()))
                        {
                            HandleProfitChasing();
                        }
                    }
                }
            }
            // When the OnBarUpdate() is called from the secondary bar series, in our case for each tick, handle stop loss and profit chasing accordingly
            else
            {
                return;
            }
        }
예제 #23
0
        private void printAuswertung()
        {
            decimal GapTradeResult;
            Color   colorTextBox;
            string  strResultDescr = "";

            GapTradeResult = (decimal)Bars.GetClose(ProcessingBarIndex - 1) - (decimal)Bars.GetOpen(ProcessingBarIndex - 1);
            if (GapTradeLong == true)
            {
                //Long
                GapTradeCounterLong    += 1;
                GapTradeResultTotalLong = GapTradeResultTotalLong + GapTradeResult;


                string strGapeTradeLong = "GapTradeLong" + ProcessingBarIndex;
                string strTradeResultLong;
                TradeDir = "Long";

                if (GapTradeResult < 0)
                {
                    if (_print_info == true)
                    {
                        Print("Fail");
                    }
                    GapTradeFailCounterLong += 1;
                    strResultDescr           = "Fail";
                    strTradeResultLong       = "Fail " + GapTradeResult.ToString();
                    colorTextBox             = colFail;
                }
                else
                {
                    GapTradeWinCounterLong += 1;
                    strResultDescr          = "Win";
                    strTradeResultLong      = "Win " + GapTradeResult.ToString();
                    colorTextBox            = colWin;
                }
                AddChartText(strGapeTradeLong, true, strTradeResultLong, Time[1], Bars.GetHigh(ProcessingBarIndex - 1) + (100 * TickSize), 9, Color.Black, new Font("Arial", 9), StringAlignment.Center, Color.Black, colorTextBox, 70);
            }
            else if (GapTradeShort == true)
            {
                //Short
                GapTradeCounterShort    += 1;
                GapTradeResultTotalShort = GapTradeResultTotalShort + GapTradeResult;


                string strGapeTradeShort = "GapTradeLong" + ProcessingBarIndex;
                string strTradeResultShort;
                TradeDir = "Short";

                if (GapTradeResult > 0)
                {
                    if (_print_info == true)
                    {
                        Print("Fail");
                    }
                    GapTradeFailCounterShort += 1;
                    strResultDescr            = "Fail";
                    strTradeResultShort       = "Fail " + GapTradeResult.ToString();
                    colorTextBox              = colFail;
                }
                else
                {
                    GapTradeWinCounterShort += 1;
                    strResultDescr           = "Win";
                    strTradeResultShort      = "Win " + GapTradeResult.ToString();
                    colorTextBox             = colWin;
                }
                AddChartText(strGapeTradeShort, true, strTradeResultShort, Time[1], Bars.GetLow(ProcessingBarIndex - 1) - (100 * TickSize), 9, Color.Black, new Font("Arial", 9), StringAlignment.Center, Color.Black, colorTextBox, 70);
            }
            if (_print_info == true)
            {
                Print("Gap Trade Result: " + GapTradeResult);
            }

            if (dev_mode == true)
            {
                Print(Instrument.Name + ";" + Math.Round(GapSize, 2) + ";" + GapTradeResult + ";" + strResultDescr + ";" + TradeDir);
            }
        }
예제 #24
0
        protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask)
        {
            if (SessionIterator == null)
            {
                SessionIterator = new SessionIterator(bars);
            }

            if (bars.Count == 0 && tmpTime != Core.Globals.MinDate)             // Reset caching when live request trimmed existing bars
            {
                tmpTime = Core.Globals.MinDate;
            }

            bool endOfBar = true;

            if (tmpTime == Core.Globals.MinDate)
            {
                tmpTime      = time;
                tmpDayCount  = 1;
                tmpTickCount = 1;
            }
            else if (bars.Count < tmpCount && bars.Count == 0)             // Reset cache when bars are trimmed
            {
                tmpTime      = Core.Globals.MinDate;
                tmpVolume    = 0;
                tmpDayCount  = 0;
                tmpTickCount = 0;
            }
            else if (bars.Count < tmpCount && bars.Count > 0)             // Reset cache when bars are trimmed
            {
                tmpTime      = bars.GetTime(bars.Count - 1);
                tmpVolume    = bars.GetVolume(bars.Count - 1);
                tmpTickCount = bars.TickCount;
                tmpDayCount  = bars.DayCount;
            }

            switch (BarsPeriod.BaseBarsPeriodType)
            {
            case BarsPeriodType.Day:
            {
                if (bars.Count == 0 || bars.Count > 0 && (bars.LastBarTime.Month < time.Month || bars.LastBarTime.Year < time.Year))
                {
                    tmpTime        = time.Date;
                    bars.LastPrice = close;
                    newSession     = true;
                }
                else
                {
                    tmpTime        = time.Date;
                    tmpVolume     += volume;
                    bars.LastPrice = close;
                    tmpDayCount++;

                    if (tmpDayCount < BarsPeriod.BaseBarsPeriodValue || bars.Count > 0 && bars.LastBarTime.Date == time.Date)
                    {
                        endOfBar = false;
                    }
                }
                break;
            }

            case BarsPeriodType.Minute:
            {
                if (bars.Count == 0 || SessionIterator.IsNewSession(time, isBar) && bars.IsResetOnNewTradingDay)
                {
                    tmpTime    = TimeToBarTimeMinute(bars, time, isBar);
                    newSession = true;
                    tmpVolume  = 0;
                }
                else
                {
                    if (!isBar && time < bars.LastBarTime || isBar && time <= bars.LastBarTime)
                    {
                        tmpTime  = bars.LastBarTime;
                        endOfBar = false;
                    }
                    else
                    {
                        tmpTime = TimeToBarTimeMinute(bars, time, isBar);
                    }

                    tmpVolume += volume;
                }
                break;
            }

            case BarsPeriodType.Month:
            {
                if (tmpTime == Core.Globals.MinDate)
                {
                    tmpTime = TimeToBarTimeMonth(time, BarsPeriod.BaseBarsPeriodValue);

                    if (bars.Count == 0)
                    {
                        break;
                    }

                    endOfBar = false;
                }
                else if (time.Month <= tmpTime.Month && time.Year == tmpTime.Year || time.Year < tmpTime.Year)
                {
                    tmpVolume     += volume;
                    bars.LastPrice = close;
                    endOfBar       = false;
                }
                break;
            }

            case BarsPeriodType.Second:
            {
                if (SessionIterator.IsNewSession(time, isBar))
                {
                    tmpTime = TimeToBarTimeSecond(bars, time, isBar);

                    if (bars.Count == 0)
                    {
                        break;
                    }

                    endOfBar   = false;
                    newSession = true;
                }
                else if (time <= tmpTime)
                {
                    tmpVolume     += volume;
                    bars.LastPrice = close;
                    endOfBar       = false;
                }
                else
                {
                    tmpTime = TimeToBarTimeSecond(bars, time, isBar);
                }
                break;
            }

            case BarsPeriodType.Tick:
            {
                if (SessionIterator.IsNewSession(time, isBar))
                {
                    SessionIterator.GetNextSession(time, isBar);
                    newSession   = true;
                    tmpTime      = time;
                    tmpTickCount = 1;

                    if (bars.Count == 0)
                    {
                        break;
                    }

                    endOfBar = false;
                }
                else if (BarsPeriod.BaseBarsPeriodValue > 1 && tmpTickCount < BarsPeriod.BaseBarsPeriodValue)
                {
                    tmpTime    = time;
                    tmpVolume += volume;
                    tmpTickCount++;
                    bars.LastPrice = close;
                    endOfBar       = false;
                }
                else
                {
                    tmpTime = time;
                }
                break;
            }

            case BarsPeriodType.Volume:
            {
                if (SessionIterator.IsNewSession(time, isBar))
                {
                    SessionIterator.GetNextSession(time, isBar);
                    newSession = true;
                }
                else if (bars.Count == 0 && volume > 0)
                {
                    break;
                }
                else
                {
                    tmpVolume += volume;
                    if (tmpVolume < BarsPeriod.BaseBarsPeriodValue)
                    {
                        bars.LastPrice = close;
                        endOfBar       = false;
                    }
                    else if (tmpVolume == 0)
                    {
                        endOfBar = false;
                    }
                }

                tmpTime = time;

                break;
            }

            case BarsPeriodType.Week:
            {
                if (tmpTime == Core.Globals.MinDate)
                {
                    tmpTime = TimeToBarTimeWeek(time.Date, tmpTime.Date, BarsPeriod.BaseBarsPeriodValue);

                    if (bars.Count == 0)
                    {
                        break;
                    }

                    endOfBar = false;
                }
                else if (time.Date <= tmpTime.Date)
                {
                    tmpVolume     += volume;
                    bars.LastPrice = close;
                    endOfBar       = false;
                }
                break;
            }

            case BarsPeriodType.Year:
            {
                if (tmpTime == Core.Globals.MinDate)
                {
                    tmpTime = TimeToBarTimeYear(time, BarsPeriod.BaseBarsPeriodValue);

                    if (bars.Count == 0)
                    {
                        break;
                    }

                    endOfBar = false;
                }
                else if (time.Year <= tmpTime.Year)
                {
                    tmpVolume     += volume;
                    bars.LastPrice = close;
                    endOfBar       = false;
                }
                break;
            }
            }

            if (bars.Count > 0 && tmpTime < bars.GetTime(bars.Count - 1) && BarsPeriod.BaseBarsPeriodType == BarsPeriodType.Second)
            {
                tmpTime = bars.GetTime(bars.Count - 1);
            }

            if (bars.Count == 0 || newSession && IsIntraday)
            {
                AddBar(bars, open, close, close, close, tmpTime, volume);
                upTrend           = open < close;
                newSessionIdx     = bars.Count - 1;
                newSession        = false;
                firstBarOfSession = true;
                anchorPrice       = close;
                switchPrice       = open;
            }
            else if (firstBarOfSession && endOfBar == false)
            {
                double prevOpen = bars.GetOpen(bars.Count - 1);
                RemoveLastBar(bars);
                if (SessionIterator.IsNewSession(tmpTime, true))
                {
                    SessionIterator.GetNextSession(tmpTime, true);
                }
                AddBar(bars, prevOpen, close, close, close, tmpTime, tmpVolume);
                upTrend     = prevOpen < close;
                anchorPrice = close;
            }
            else
            {
                int    breakCount = BarsPeriod.Value;
                double breakMax   = double.MinValue;
                double breakMin   = double.MaxValue;

                if (firstBarOfSession)
                {
                    AddBar(bars, anchorPrice, close, close, close, tmpTime, volume);
                    firstBarOfSession = false;
                    tmpVolume         = volume;
                    tmpTime           = Core.Globals.MinDate;
                    return;
                }

                if (bars.Count - newSessionIdx - 1 < breakCount)
                {
                    breakCount = bars.Count - (newSessionIdx + 1);
                }

                for (int k = 1; k <= breakCount; k++)
                {
                    breakMax = Math.Max(breakMax, bars.GetOpen(bars.Count - k - 1));
                    breakMax = Math.Max(breakMax, bars.GetClose(bars.Count - k - 1));
                    breakMin = Math.Min(breakMin, bars.GetOpen(bars.Count - k - 1));
                    breakMin = Math.Min(breakMin, bars.GetClose(bars.Count - k - 1));
                }

                bars.LastPrice = close;

                if (upTrend)
                {
                    if (endOfBar)
                    {
                        bool adding = false;
                        if (bars.Instrument.MasterInstrument.Compare(bars.GetClose(bars.Count - 1), anchorPrice) > 0)
                        {
                            anchorPrice = bars.GetClose(bars.Count - 1);
                            switchPrice = bars.GetOpen(bars.Count - 1);
                            tmpVolume   = volume;
                            adding      = true;
                        }
                        else
                        if (bars.Instrument.MasterInstrument.Compare(breakMin, bars.GetClose(bars.Count - 1)) > 0)
                        {
                            anchorPrice = bars.GetClose(bars.Count - 1);
                            switchPrice = bars.GetOpen(bars.Count - 1);
                            tmpVolume   = volume;
                            upTrend     = false;
                            adding      = true;
                        }

                        if (adding)
                        {
                            double tmpOpen = upTrend ? Math.Min(Math.Max(switchPrice, close), anchorPrice) : Math.Max(Math.Min(switchPrice, close), anchorPrice);
                            AddBar(bars, tmpOpen, close, close, close, tmpTime, volume);
                        }
                        else
                        {
                            RemoveLastBar(bars);
                            double tmpOpen = Math.Min(Math.Max(switchPrice, close), anchorPrice);
                            if (SessionIterator.IsNewSession(tmpTime, true))
                            {
                                SessionIterator.GetNextSession(tmpTime, true);
                            }
                            AddBar(bars, tmpOpen, close, close, close, tmpTime, tmpVolume);
                        }
                    }
                    else
                    {
                        RemoveLastBar(bars);
                        double tmpOpen = Math.Min(Math.Max(switchPrice, close), anchorPrice);
                        if (SessionIterator.IsNewSession(tmpTime, true))
                        {
                            SessionIterator.GetNextSession(tmpTime, true);
                        }
                        AddBar(bars, tmpOpen, close, close, close, tmpTime, tmpVolume);
                    }
                }
                else
                if (endOfBar)
                {
                    bool adding = false;
                    if (bars.Instrument.MasterInstrument.Compare(bars.GetClose(bars.Count - 1), anchorPrice) < 0)
                    {
                        anchorPrice = bars.GetClose(bars.Count - 1);
                        switchPrice = bars.GetOpen(bars.Count - 1);
                        tmpVolume   = volume;
                        adding      = true;
                    }
                    else
                    if (bars.Instrument.MasterInstrument.Compare(breakMax, bars.GetClose(bars.Count - 1)) < 0)
                    {
                        anchorPrice = bars.GetClose(bars.Count - 1);
                        switchPrice = bars.GetOpen(bars.Count - 1);
                        tmpVolume   = volume;
                        upTrend     = true;
                        adding      = true;
                    }

                    if (adding)
                    {
                        double tmpOpen = upTrend ? Math.Min(Math.Max(switchPrice, close), anchorPrice) : Math.Max(Math.Min(switchPrice, close), anchorPrice);
                        AddBar(bars, tmpOpen, close, close, close, tmpTime, volume);
                    }
                    else
                    {
                        RemoveLastBar(bars);
                        double tmpOpen = Math.Max(Math.Min(switchPrice, close), anchorPrice);
                        if (SessionIterator.IsNewSession(tmpTime, true))
                        {
                            SessionIterator.GetNextSession(tmpTime, true);
                        }
                        AddBar(bars, tmpOpen, close, close, close, tmpTime, tmpVolume);
                    }
                }
                else
                {
                    RemoveLastBar(bars);
                    double tmpOpen = Math.Max(Math.Min(switchPrice, close), anchorPrice);
                    if (SessionIterator.IsNewSession(tmpTime, true))
                    {
                        SessionIterator.GetNextSession(tmpTime, true);
                    }
                    AddBar(bars, tmpOpen, close, close, close, tmpTime, tmpVolume);
                }
            }

            if (endOfBar)
            {
                tmpTime = Core.Globals.MinDate;
            }

            tmpCount = bars.Count;
        }
예제 #25
0
        /// <summary>
        /// Called when the indicator is plotted.
        /// </summary>
        public override void Plot(Graphics graphics, Rectangle bounds, double min, double max)
        {
            int lastBar     = Math.Min(this.LastBarIndexPainted, Bars.Count - 1);
            int barsPainted = ChartControl.BarsPainted;
            int firstBar    = this.FirstBarIndexPainted;

            // Find highest and lowest price points
            double highPrice = 0;
            double lowPrice  = double.MaxValue;

            for (int idx = firstBar; idx <= lastBar && idx >= 0; idx++)
            {
                highPrice = Math.Max(highPrice, Bars.GetHigh(idx));
                lowPrice  = Math.Min(lowPrice, Bars.GetLow(idx));
            }

            int    volumeBarCount = this.BarCount;
            double priceRange     = highPrice - lowPrice;
            double priceBoxSize   = priceRange / volumeBarCount;

            double volumeMax = 0;

            // Pass 1: Fill all VolumeInfo structures with appropriate data
            for (int i = 0; i < volumeBarCount; i++)
            {
                double priceUpper = lowPrice + priceBoxSize * (i + 1);
                double priceLower = lowPrice + priceBoxSize * i;

                double priceVolumeUp   = 0;
                double priceVolumeDown = 0;

                for (int idx = firstBar; idx <= lastBar; idx++)
                {
                    double checkPrice;
                    switch (PriceType)
                    {
                    case PriceType.Open:            checkPrice = Bars.GetOpen(idx); break;

                    case PriceType.Close:           checkPrice = Bars.GetClose(idx); break;

                    case PriceType.High:            checkPrice = Bars.GetHigh(idx); break;

                    case PriceType.Low:                     checkPrice = Bars.GetLow(idx);  break;

                    case PriceType.Median:          checkPrice = (Bars.GetHigh(idx) + Bars.GetLow(idx)) / 2; break;

                    case PriceType.Typical:         checkPrice = (Bars.GetHigh(idx) + Bars.GetLow(idx) + Bars.GetClose(idx)) / 3; break;

                    case PriceType.Weighted:        checkPrice = (Bars.GetHigh(idx) + Bars.GetLow(idx) + 2 * Bars.GetClose(idx)) / 4; break;

                    default:                                        checkPrice = Bars.GetClose(idx); break;
                    }

                    if (checkPrice >= priceLower && checkPrice < priceUpper)
                    {
                        if (Bars.GetOpen(idx) < Bars.GetClose(idx))
                        {
                            priceVolumeUp += Bars.GetVolume(idx);
                        }
                        else
                        {
                            priceVolumeDown += Bars.GetVolume(idx);
                        }
                    }
                }

                volumeInfo[i].up    = priceVolumeUp;
                volumeInfo[i].down  = priceVolumeDown;
                volumeInfo[i].total = (double)priceVolumeUp + (double)priceVolumeDown;

                volumeMax = Math.Max(volumeMax, volumeInfo[i].total);
            }

            // Pass 2: Paint the volume bars
            for (int i = 0; i < Math.Min(volumeBarCount, lastBar - firstBar + 1); i++)
            {
                double priceUpper = lowPrice + priceBoxSize * (i + 1);
                double priceLower = lowPrice + priceBoxSize * i;

                int yUpper = GetYPos(priceUpper, bounds, min, max) + barSpacing;
                int yLower = GetYPos(priceLower, bounds, min, max);

                int barWidthUp   = (int)((bounds.Width / 2) * (volumeInfo[i].up / volumeMax));
                int barWidthDown = (int)((bounds.Width / 2) * (volumeInfo[i].down / volumeMax));

                if (barWidthDown == int.MinValue || barWidthUp == int.MinValue)                         // overflow?
                {
                    continue;
                }

                int barWidth = barWidthUp + barWidthDown;

                graphics.FillRectangle(barBrushUp, new Rectangle(
                                           bounds.X, yUpper,
                                           barWidthUp, Math.Abs(yUpper - yLower)));

                graphics.FillRectangle(barBrushDown, new Rectangle(
                                           bounds.X + barWidthUp, yUpper,
                                           barWidthDown, Math.Abs(yUpper - yLower)));

                if (drawLines == true)
                {
                    // Lower line
                    graphics.DrawLine(linePen,
                                      bounds.X, yLower,
                                      bounds.X + bounds.Width, yLower);

                    // Upper line (only at the very top)
                    if (i == volumeBarCount - 1)
                    {
                        graphics.DrawLine(linePen,
                                          bounds.X, yUpper,
                                          bounds.X + bounds.Width, yUpper);
                    }
                }
            }
        }
예제 #26
0
        protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
            if (IsInHitTest)
            {
                return;
            }

            int    lastBar   = ChartBars.ToIndex;
            int    firstBar  = ChartBars.FromIndex;
            double highPrice = 0;
            double lowPrice  = double.MaxValue;

            SharpDX.Direct2D1.Brush brushDown = BarDownBrush.ToDxBrush(RenderTarget);
            SharpDX.Direct2D1.Brush lineBrush = LineBrush.ToDxBrush(RenderTarget);
            SharpDX.Direct2D1.Brush brushUp   = BarUpBrush.ToDxBrush(RenderTarget);
            brushDown.Opacity = (float)(Opacity / 100.0);
            brushUp.Opacity   = (float)(Opacity / 100.0);

            for (int idx = firstBar; idx <= lastBar && idx >= 0; idx++)
            {
                highPrice = Math.Max(highPrice, Bars.GetHigh(idx));
                lowPrice  = Math.Min(lowPrice, Bars.GetLow(idx));
            }

            int    volumeBarCount = BarCount;
            double priceRange     = highPrice - lowPrice;
            double priceBoxSize   = priceRange / volumeBarCount;
            double volumeMax      = 0;

            // Pass 1: Fill all VolumeInfo structures with appropriate data
            for (int i = 0; i < volumeBarCount; i++)
            {
                double priceUpper = lowPrice + priceBoxSize * (i + 1);
                double priceLower = lowPrice + priceBoxSize * i;

                double priceVolumeUp   = 0;
                double priceVolumeDown = 0;

                for (int idx = firstBar; idx <= lastBar; idx++)
                {
                    double checkPrice;

                    PriceSeries series = (Inputs[0] as PriceSeries);

                    switch (series.PriceType)
                    {
                    case PriceType.Open:            checkPrice = Bars.GetOpen(idx); break;

                    case PriceType.Close:           checkPrice = Bars.GetClose(idx); break;

                    case PriceType.High:            checkPrice = Bars.GetHigh(idx); break;

                    case PriceType.Low:                     checkPrice = Bars.GetLow(idx); break;

                    case PriceType.Median:          checkPrice = (Bars.GetHigh(idx) + Bars.GetLow(idx)) / 2; break;

                    case PriceType.Typical:         checkPrice = (Bars.GetHigh(idx) + Bars.GetLow(idx) + Bars.GetClose(idx)) / 3; break;

                    case PriceType.Weighted:        checkPrice = (Bars.GetHigh(idx) + Bars.GetLow(idx) + 2 * Bars.GetClose(idx)) / 4; break;

                    default:                                        checkPrice = Bars.GetClose(idx); break;
                    }

                    if (checkPrice >= priceLower && checkPrice < priceUpper)
                    {
                        if (Bars.GetOpen(idx) < Bars.GetClose(idx))
                        {
                            priceVolumeUp += Bars.GetVolume(idx);
                        }
                        else
                        {
                            priceVolumeDown += Bars.GetVolume(idx);
                        }
                    }
                }

                volumeInfo[i].up    = priceVolumeUp;
                volumeInfo[i].down  = priceVolumeDown;
                volumeInfo[i].total = priceVolumeUp + priceVolumeDown;

                volumeMax = Math.Max(volumeMax, volumeInfo[i].total);
            }

            // Pass 2: Paint the volume bars
            for (int i = 0; i < Math.Min(volumeBarCount, lastBar - firstBar + 1); i++)
            {
                double priceUpper   = lowPrice + priceBoxSize * (i + 1);
                double priceLower   = lowPrice + priceBoxSize * i;
                int    yUpper       = Convert.ToInt32(chartScale.GetYByValue(priceUpper)) + BarSpacing;
                int    yLower       = Convert.ToInt32(chartScale.GetYByValue(priceLower));
                int    barWidthUp   = (int)((chartScale.Height / 2) * (volumeInfo[i].up / volumeMax));
                int    barWidthDown = (int)((chartScale.Height / 2) * (volumeInfo[i].down / volumeMax));

                SharpDX.RectangleF rect = new SharpDX.RectangleF(ChartPanel.X, yUpper, barWidthUp, Math.Abs(yUpper - yLower));
                RenderTarget.FillRectangle(rect, brushUp);
                RenderTarget.DrawRectangle(rect, brushUp);

                SharpDX.RectangleF rect2 = new SharpDX.RectangleF(ChartPanel.X + barWidthUp, yUpper, barWidthDown, Math.Abs(yUpper - yLower));
                RenderTarget.DrawRectangle(rect2, brushDown);
                RenderTarget.FillRectangle(rect2, brushDown);

                if (DrawLines)
                {
                    RenderTarget.DrawLine(new SharpDX.Vector2(ChartPanel.X, yLower), new SharpDX.Vector2(ChartPanel.X + ChartPanel.W, yLower), lineBrush);
                    if (i == volumeBarCount - 1)
                    {
                        RenderTarget.DrawLine(new SharpDX.Vector2(ChartPanel.X, yUpper), new SharpDX.Vector2(ChartPanel.X + ChartPanel.W, yUpper), lineBrush);
                    }
                }
            }

            lineBrush.Dispose();
            brushDown.Dispose();
            brushUp.Dispose();
        }
예제 #27
0
        protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask)
        {
            if (SessionIterator == null)
            {
                SessionIterator = new SessionIterator(bars);
            }

            offset = bars.BarsPeriod.Value * bars.Instrument.MasterInstrument.TickSize;
            bool isNewSession = SessionIterator.IsNewSession(time, isBar);

            if (isNewSession)
            {
                SessionIterator.GetNextSession(time, isBar);
            }

            if (bars.Count == 0 || bars.IsResetOnNewTradingDay && isNewSession)
            {
                if (bars.Count > 0)
                {
                    // Close out last bar in session and set open == close
                    double   lastBarClose  = bars.GetClose(bars.Count - 1);
                    DateTime lastBarTime   = bars.GetTime(bars.Count - 1);
                    long     lastBarVolume = bars.GetVolume(bars.Count - 1);
                    RemoveLastBar(bars);
                    AddBar(bars, lastBarClose, lastBarClose, lastBarClose, lastBarClose, lastBarTime, lastBarVolume);
                }

                renkoHigh = close + offset;
                renkoLow  = close - offset;

                isNewSession = SessionIterator.IsNewSession(time, isBar);
                if (isNewSession)
                {
                    SessionIterator.GetNextSession(time, isBar);
                }

                AddBar(bars, close, close, close, close, time, volume);
                bars.LastPrice = close;

                return;
            }

            double   barOpen   = bars.GetOpen(bars.Count - 1);
            double   barHigh   = bars.GetHigh(bars.Count - 1);
            double   barLow    = bars.GetLow(bars.Count - 1);
            long     barVolume = bars.GetVolume(bars.Count - 1);
            DateTime barTime   = bars.GetTime(bars.Count - 1);

            if (renkoHigh.ApproxCompare(0.0) == 0 || renkoLow.ApproxCompare(0.0) == 0)
            {
                if (bars.Count == 1)
                {
                    renkoHigh = barOpen + offset;
                    renkoLow  = barOpen - offset;
                }
                else if (bars.GetClose(bars.Count - 2) > bars.GetOpen(bars.Count - 2))
                {
                    renkoHigh = bars.GetClose(bars.Count - 2) + offset;
                    renkoLow  = bars.GetClose(bars.Count - 2) - offset * 2;
                }
                else
                {
                    renkoHigh = bars.GetClose(bars.Count - 2) + offset * 2;
                    renkoLow  = bars.GetClose(bars.Count - 2) - offset;
                }
            }

            if (close.ApproxCompare(renkoHigh) >= 0)
            {
                if (barOpen.ApproxCompare(renkoHigh - offset) != 0 ||
                    barHigh.ApproxCompare(Math.Max(renkoHigh - offset, renkoHigh)) != 0 ||
                    barLow.ApproxCompare(Math.Min(renkoHigh - offset, renkoHigh)) != 0)
                {
                    RemoveLastBar(bars);
                    AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, renkoHigh), Math.Min(renkoHigh - offset, renkoHigh), renkoHigh, barTime, barVolume);
                }

                renkoLow  = renkoHigh - 2.0 * offset;
                renkoHigh = renkoHigh + offset;

                isNewSession = SessionIterator.IsNewSession(time, isBar);
                if (isNewSession)
                {
                    SessionIterator.GetNextSession(time, isBar);
                }

                while (close.ApproxCompare(renkoHigh) >= 0)                     // Add empty bars to fill gap if price jumps
                {
                    AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, renkoHigh), Math.Min(renkoHigh - offset, renkoHigh), renkoHigh, time, 0);
                    renkoLow  = renkoHigh - 2.0 * offset;
                    renkoHigh = renkoHigh + offset;
                }

                // Add final partial bar
                AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, close), Math.Min(renkoHigh - offset, close), close, time, volume);
            }
            else
            if (close.ApproxCompare(renkoLow) <= 0)
            {
                if (barOpen.ApproxCompare(renkoLow + offset) != 0 ||
                    barHigh.ApproxCompare(Math.Max(renkoLow + offset, renkoLow)) != 0 ||
                    barLow.ApproxCompare(Math.Min(renkoLow + offset, renkoLow)) != 0)
                {
                    RemoveLastBar(bars);
                    AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, barTime, barVolume);
                }

                renkoHigh = renkoLow + 2.0 * offset;
                renkoLow  = renkoLow - offset;

                isNewSession = SessionIterator.IsNewSession(time, isBar);
                if (isNewSession)
                {
                    SessionIterator.GetNextSession(time, isBar);
                }

                while (close.ApproxCompare(renkoLow) <= 0)                              // Add empty bars to fill gap if price jumps
                {
                    AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, time, 0);
                    renkoHigh = renkoLow + 2.0 * offset;
                    renkoLow  = renkoLow - offset;
                }

                // Add final partial bar
                AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, close), Math.Min(renkoLow + offset, close), close, time, volume);
            }
            else
            {
                UpdateBar(bars, close, close, close, time, volume);
            }

            bars.LastPrice = close;
        }
        //protected override void OnBarUpdate()
        //{
        //    //TODO: Write your owner OnBarUpdate handling


        //    //DrawArrowUp("Arrowup" + CurrentBar, true, Bars.GetTime(Count - 1), Bars.GetLow(CurrentBar) - 300 * TickSize, Color.Red);
        //    //DrawArrowDown("Arrowdown" + CurrentBar, true, Bars.GetTime(Count - 1), Bars.GetHigh(CurrentBar) + 300 * TickSize, Color.Green);

        //    //Occurred.Set(-1);
        //    //Entry.Set(Close[0]);

        //}

        protected override void OnBarUpdate()
        {
            //MyGap.Set(Input[0]);

            if (Bars != null && Bars.Count > 0)
            //             && TimeFrame.Periodicity == DatafeedHistoryPeriodicity.Minute
            //             && TimeFrame.PeriodicityValue == 15)
            {
            }
            else
            {
                return;
            }

            if (Bars.BarsSinceSession == 0)
            {
                sessionprocessed = false;
            }

            //08.00, 08.15, 08.30, 08.45, 09.00 sind abgeschlossen -> es ist 09.15)
            //                if(Bars.BarsSinceSession == 5)
            if (ToTime(Bars.GetTime(CurrentBar)) > 90000 && //größer 09.00 geht für 15M und 1Std (und 1Tag?)
                sessionprocessed == false)       //Tag noch nicht verarbeitet
            {
                sessionprocessed = true;
                GapTradeLong     = GapTradeShort = false;

                IBar   GapOpenBar = Bars.Where(x => x.Time.Date == Bars[0].Time.Date).FirstOrDefault(); //liefert erster kerze des tages
                double GapOpen    = GapOpenBar.Open;

                double   LastDayClose     = PriorDayOHLC().PriorClose[0];
                double   GapSize          = GapOpen - LastDayClose;
                DateTime LastDayCloseDate = Bars.GetTime(Count - 7);
                DateTime LastPeriod       = Time[1];

                if (LastDayClose != null &&
                    Math.Abs(LastDayClose - GapOpen) > _PunkteGapMin &&
                    Math.Abs(LastDayClose - GapOpen) < _PunkteGapMax)
                {  //Wenn Gap größer 50 und kleiner 100
                    existgap = true;


                    //Gap markieren (08.00 - 09.15)
                    string strMyRect    = "MyRect" + Count;
                    string strMyGapSize = "MyGapSize" + Count;


                    if (LastDayClose - GapOpen < 0)   //Long
                    {
                        //Long
                        //DrawRectangle(strMyRect, true, LastDayCloseDate, LastDayClose, LastPeriod, HighestHighPrice(5)[0], _col_gap, _col_gap, 70);
                        DrawText(strMyGapSize, true, Math.Round(GapSize, 1).ToString(), LastDayCloseDate, LastDayClose + 25, 9, Color.Black, new Font("Areal", 9), StringAlignment.Center, Color.Black, Color.Azure, 1);

                        // if (LinReg(5)[0] > GapOpen)
                        if (LinReg(Closes[0], 5)[0] > GapOpen)
                        {
                            //Chancenreicher SuccessTrade
                            string strArrowUp = "ArrowUp" + Bars.GetTime(CurrentBar);
                            DrawArrowUp(strArrowUp, true, Bars.GetTime(Count - 1), Bars.GetOpen(CurrentBar) - 300 * TickSize, Color.Green);
                            GapTradeLong = true;

                            Occurred.Set(1);
                            Entry.Set(Bars.GetOpen(CurrentBar));
                        }
                    }
                    else
                    {
                        //Short
                        //DrawRectangle(strMyRect, true, LastDayCloseDate, LastDayClose, LastPeriod, LowestLowPrice(5)[0], Color.Pink, Color.Pink, 70);
                        DrawText(strMyGapSize, true, Math.Round(GapSize, 1).ToString(), LastDayCloseDate, LastDayClose - 25, 9, Color.Black, new Font("Areal", 9), StringAlignment.Center, Color.Black, Color.Azure, 1);

                        if (LinReg(Closes[0], 5)[0] < GapOpen)
                        {
                            ////Chancenreicher SuccessTrade
                            string strArrowDown = "ArrowDown" + Bars.GetTime(CurrentBar);
                            DrawArrowDown(strArrowDown, true, Bars.GetTime(Count - 1), Bars.GetOpen(CurrentBar) + 300 * TickSize, Color.Red);
                            GapTradeShort = true;

                            Occurred.Set(-1);
                            Entry.Set(Bars.GetOpen(CurrentBar));
                        }
                    }

                    if (GapTradeShort == true || GapTradeLong == true)
                    {
                        Print("------------------" + Time[5] + "------------------");
                        Print("LineReg: " + Math.Round(LinReg(5)[0]), 1);
                        Print("Gap Open: " + GapOpen);
                    }
                }
                else
                {
                    existgap = false;
                }
            }

//09.15. - 09.30 Kerze
            else if (Bars.BarsSinceSession == 6 && existgap == true)
            {
                //Auswertung
                decimal GapTradeResult;
                Color   colorTextBox;

                GapTradeResult = (decimal)Bars.GetClose(CurrentBar - 1) - (decimal)Bars.GetOpen(CurrentBar - 1);
                if (GapTradeLong == true)
                {
                    //Long
                    GapTradeCounterLong    += 1;
                    GapTradeResultTotalLong = GapTradeResultTotalLong + GapTradeResult;


                    string strGapeTradeLong = "GapTradeLong" + CurrentBar;
                    string strTradeResultLong;

                    if (GapTradeResult < 0)
                    {
                        Print("FAAAAAAAAAAAAAAAIIIIIIIIIIIIIILLLLLLLLLL");
                        GapTradeFailCounterLong += 1;
                        strTradeResultLong       = "Fail " + GapTradeResult.ToString();
                        colorTextBox             = colFail;
                    }
                    else
                    {
                        GapTradeWinCounterLong += 1;
                        strTradeResultLong      = "Win " + GapTradeResult.ToString();
                        colorTextBox            = colWin;
                    }
                    DrawText(strGapeTradeLong, true, strTradeResultLong, Time[1], Bars.GetHigh(CurrentBar - 1) + 10, 9, Color.Black, new Font("Areal", 9), StringAlignment.Center, Color.Black, colorTextBox, 70);
                }
                else if (GapTradeShort == true)
                {
                    //Short
                    GapTradeCounterShort    += 1;
                    GapTradeResultTotalShort = GapTradeResultTotalShort - GapTradeResult;


                    string strGapeTradeShort = "GapTradeLong" + CurrentBar;
                    string strTradeResultShort;

                    if (GapTradeResult > 0)
                    {
                        Print("FAAAAAAAAAAAAAAAIIIIIIIIIIIIIILLLLLLLLLL");
                        GapTradeFailCounterShort += 1;
                        strTradeResultShort       = "Fail " + GapTradeResult.ToString();
                        colorTextBox              = colFail;
                    }
                    else
                    {
                        GapTradeWinCounterShort += 1;
                        strTradeResultShort      = "Win " + GapTradeResult.ToString();
                        colorTextBox             = colWin;
                    }
                    DrawText(strGapeTradeShort, true, strTradeResultShort, Time[1], Bars.GetLow(CurrentBar - 1) - 10, 9, Color.Black, new Font("Areal", 9), StringAlignment.Center, Color.Black, colorTextBox, 70);
                }

                Print("Gap Trade Result: " + GapTradeResult);
            }

            if (Count == Bars.Count - 1)
            {
                Print("Total Trades Long:  " + GapTradeCounterLong);
                Print("Wins Long: " + GapTradeWinCounterLong);
                Print("Fails Long: " + GapTradeFailCounterLong);

                Print("Total Trades Short: " + GapTradeCounterShort);
                Print("Wins Short: " + GapTradeWinCounterShort);
                Print("Fails Short: " + GapTradeFailCounterShort);

                if (GapTradeCounterLong > 0)
                {
                    Print("Avg Long: " + (GapTradeResultTotalLong / GapTradeCounterLong));
                }
                if (GapTradeCounterShort > 0)
                {
                    Print("Avg Short: " + (GapTradeResultTotalShort / GapTradeCounterShort));
                }
            }
        }
예제 #29
0
        public override void Plot(Graphics graphics, Rectangle bounds, double min, double max)
        {
            if ((Bars == null) || (chartedMax < 0))
            {
                return;
            }
            backBrush.Color = ChartControl.BackColor;

            int lastBar  = Math.Min(LastBarIndexPainted, Bars.Count - 1);
            int firstBar = FirstBarIndexPainted;

            var   th         = ChartControl.GetYByValue(this, chartedMax) - ChartControl.GetYByValue(this, chartedMax + TickSize);
            float halfHeight = th / 2f;

            // a few heights and widths to set...
            bigrect.Height   = th;
            totalsrect.Width = ChartControl.BarSpace;
            bigrect.Width    = Math.Max(totalsrect.Width - (combinedvol?5:0), 1);
            lilrect.Height   = th;
            lilrect.Width    = bigrect.Width / 2.0f - 3;

            #region setupFonts
            if ((ChartControl.BarSpace != barWidth) || (th != tickHeight))
            {
                // need to recompute the right fonts, then...
                //Print("New TickHeight! " + th + " vs. "+tickHeight); // DEBUG
                barWidth   = ChartControl.BarSpace;
                tickHeight = th;
                if (deltaFont != null)
                {
                    deltaFont.Dispose();
                }
                if (totalsFont != null)
                {
                    totalsFont.Dispose();
                }
                deltaFont  = null;
                totalsFont = null;
                float totwidth = Math.Min(Math.Max(totalsrect.Width / 4, 2), 18);
                totalsFont = new Font(FontFamily.GenericMonospace, totwidth, GraphicsUnit.Pixel);
                float delwidth = Math.Max(bigrect.Width / 6, 2);
                deltaFont = new Font(FontFamily.GenericMonospace, delwidth, GraphicsUnit.Pixel);
                if (deltaFont.Height > th)
                {
                    deltaFont.Dispose();
                    deltaFont = new Font(FontFamily.GenericMonospace, Math.Max(bigrect.Height, 2), GraphicsUnit.Pixel);
                }
            }
            totalsrect.Height = totalsFont.Height;
            #endregion setupFonts

            // set up the dividing line for the summary information
            #region setupdivider
            double linprice = chartedMin;
            float  linlvl   = ChartControl.GetYByValue(this, linprice - 0.5 * TickSize);
            if (displaytotals)
            {
                // put the linlvl at the bottom, if that's lower than just below the
                // lowest chart price.
                var fromBottom = bounds.Bottom - totalsFont.Height * 4.5f;
                //Print("linlvl vs. frombottom: "+linlvl+" "+fromBottom);
                if (fromBottom > linlvl)
                {
                    linlvl   = fromBottom;
                    linprice = Bars.Instrument.MasterInstrument.Round2TickSize(min + TickSize * (-1 + (totalsFont.Height * 4.5f) / tickHeight));
                    while (ChartControl.GetYByValue(this, linprice) < linlvl)
                    {
                        linprice -= TickSize;
                    }
                    while (ChartControl.GetYByValue(this, linprice) > linlvl)
                    {
                        linprice += TickSize;
                    }
                    linprice = Bars.Instrument.MasterInstrument.Round2TickSize(linprice);
                }
            }
            else
            {
                linprice = -1;
                linlvl   = ChartControl.GetYByValue(this, min) + 999;
            }
            //Print("Final: "+linlvl);
            #endregion setupdivider

            // if we are using the graphical display, find the largest volume
            #region findlargestvol
            long mvol = 1;
            if (displaycandles && displaygraphical)
            {
                for (int indx = firstBar; indx <= lastBar; ++indx)
                {
                    if ((indx <= CurrentBar) && (indx >= 1))
                    {
                        var ed = extdat.getExtraData(CurrentBar - indx, this.Bars, CurrentBar);
                        if (ed != null)
                        {
                            mvol = Math.Max(mvol, ed.findLargestLevel(combinedvol));
                        }
                    }
                }
            }
            #endregion findlargestvol

            if (displaytotals || displaycandles)
            {
                for (int indx = firstBar; indx <= lastBar; ++indx)
                {
                    if ((indx <= CurrentBar) && (indx >= 1))
                    {
                        var ed = extdat.getExtraData(CurrentBar - indx, this.Bars, CurrentBar);
                        if (ed != null)
                        {
                            // set up for the bar's  location
                            #region barXYlocation
                            int x = ChartControl.GetXByBarIdx(BarsArray[0], indx);
                            totalsrect.X = x - 0.5f * barWidth;
                            bigrect.X    = totalsrect.X + (combinedvol?5:0);
                            #endregion barXYlocation

                            // draw on the candle
                            #region drawcandle
                            if (displaycandles)
                            {
                                double miny    = Bars.GetLow(indx);
                                double maxy    = Bars.GetHigh(indx);
                                var    candleY = ChartControl.GetYByValue(this, maxy);
                                var    candleH = ChartControl.GetYByValue(this, miny) - candleY;

                                graphics.FillRectangle(backBrush, bigrect.X, candleY - bigrect.Height, bigrect.Width, candleH + 2 * bigrect.Height);

                                var openCoord  = ChartControl.GetYByValue(this, Bars.GetOpen(indx));
                                var closeCoord = ChartControl.GetYByValue(this, Bars.GetClose(indx));
                                paintBrush.Color = ChartControl.ChartStyle.Pen2.Color;                 // candle wick color...
                                var stemX = (combinedvol?(bigrect.X - 4):(bigrect.X + lilrect.Width + 2));
                                graphics.FillRectangle(paintBrush, stemX, candleY, 2, candleH);
                                if (openCoord == closeCoord)
                                {
                                    graphics.FillRectangle(paintBrush, stemX - 1, openCoord - 1, 4, 2);
                                }
                                else if (openCoord > closeCoord)
                                {
                                    paintBrush.Color = ChartControl.UpColor;
                                    graphics.FillRectangle(paintBrush, stemX - 1, closeCoord, 4, openCoord - closeCoord);
                                }
                                else
                                {
                                    paintBrush.Color = ChartControl.DownColor;
                                    graphics.FillRectangle(paintBrush, stemX - 1, openCoord, 4, closeCoord - openCoord);
                                }

                                // now paint the bar prices...
                                #region barpainting
                                long put, pdt;                  // price upticks, price downticks
                                var  ynext       = ChartControl.GetYByValue(this, maxy) - halfHeight;
                                var  lowboundary = (miny - TickSize / 2);
                                for (double cury = maxy; cury > lowboundary; cury -= TickSize)
                                {
                                    ed.getUpDnTicksAtPrice(TickSize, cury, out put, out pdt);

                                    bigrect.Y      = ynext;
                                    ynext          = ChartControl.GetYByValue(this, cury - TickSize) - halfHeight;
                                    bigrect.Height = ynext - bigrect.Y;
                                    lilrect.Y      = bigrect.Y;
                                    lilrect.Height = bigrect.Height;

                                    if (combinedvol)
                                    {
                                        var cvol = put + pdt;
                                        if (cvol < 1)
                                        {
                                            cvol = 1;
                                        }
                                        var ratio = ((float)put) / ((float)cvol);
                                        if (ratio >= 0.75)
                                        {
                                            paintBrush.Color = upcolor;
                                        }
                                        else if (ratio <= 0.25)
                                        {
                                            paintBrush.Color = dncolor;
                                        }
                                        else
                                        {
                                            paintBrush.Color = neutcolor;
                                        }
                                        if (displaygraphical)
                                        {
                                            var w = ((float)cvol) * bigrect.Width / ((float)mvol);
                                            graphics.FillRectangle(paintBrush, bigrect.X, bigrect.Y, w, bigrect.Height);
                                        }
                                        else
                                        {
                                            graphics.DrawString(cvol.ToString(), deltaFont, paintBrush, bigrect, leftFormat);
                                        }
                                    }
                                    else
                                    {
                                        paintBrush.Color = dncolor;
                                        lilrect.X        = bigrect.X;
                                        if (displaygraphical)
                                        {
                                            var w = ((float)pdt) * lilrect.Width / ((float)mvol);
                                            graphics.FillRectangle(paintBrush, lilrect.X + lilrect.Width - w,
                                                                   lilrect.Y, w, lilrect.Height);
                                        }
                                        else
                                        {
                                            graphics.DrawString(pdt.ToString(), deltaFont, paintBrush, lilrect, rightFormat);
                                        }
                                        paintBrush.Color = upcolor;
                                        lilrect.X       += lilrect.Width + 6;
                                        if (displaygraphical)
                                        {
                                            var w = ((float)put) * lilrect.Width / ((float)mvol);
                                            graphics.FillRectangle(paintBrush, lilrect.X, lilrect.Y, w, lilrect.Height);
                                        }
                                        else
                                        {
                                            graphics.DrawString(put.ToString(), deltaFont, paintBrush, lilrect, leftFormat);
                                        }
                                    }
                                }
                                #endregion barpainting
                            }
                            #endregion drawcandle

                            // draw totals at the bottom
                            #region drawtotals
                            if (displaytotals)
                            {
                                double denom = Math.Max(1, ed.UpTicks + ed.DnTicks);

                                paintBrush.Color = upcolor;
                                totalsrect.Y     = linlvl;
                                int pctage = (int)(Math.Round((double)ed.UpTicks * 100.0 / denom));
                                graphics.DrawString(String.Format("{0}%", pctage), totalsFont, paintBrush, totalsrect, centerFormat);
                                totalsrect.Y = totalsrect.Y + totalsFont.Height;
                                graphics.DrawString(ed.UpTicks.ToString(), totalsFont, paintBrush, totalsrect, centerFormat);

                                paintBrush.Color = dncolor;
                                totalsrect.Y     = totalsrect.Y + totalsFont.Height;
                                graphics.DrawString(ed.DnTicks.ToString(), totalsFont, paintBrush, totalsrect, centerFormat);
                                totalsrect.Y = totalsrect.Y + totalsFont.Height;
                                graphics.DrawString(String.Format("{0}%", 100 - pctage), totalsFont, paintBrush, totalsrect, centerFormat);
                            }
                            #endregion drawtotals
                        }
                    }
                }
            }

            // draw the dividing line
            #region drawdivider
            if (displaytotals)
            {
                linpen.Color = neutcolor;
                graphics.DrawLine(linpen, bounds.Left, linlvl, bounds.Right, linlvl);
                //Print("totalsFont height *4 = "+(4*totalsFont.Height));
            }
            #endregion drawdivider

            // now display the volume profile, if needed...
            #region dispvolprofile
            if (displayvolprofile)
            {
                var edcbar = extdat.getExtraData(0, Bars, CurrentBar);
                if (edcbar != null)
                {
                    var  dispmax  = Bars.Instrument.MasterInstrument.Round2TickSize(max);
                    var  dispmin  = Bars.Instrument.MasterInstrument.Round2TickSize(Math.Max(linprice, min));
                    var  idxhigh  = vprofIndex(dispmax);
                    var  idxlow   = vprofIndex(dispmin);
                    long maxvprof = 1;

                    // figure out where the current bar fits in...
                    int  idxcbarh = idxhigh + (int)Math.Round((dispmax - Bars.GetHigh(CurrentBar)) / TickSize);
                    int  idxcbarl = idxhigh + (int)Math.Round((dispmax - Bars.GetLow(CurrentBar)) / TickSize);
                    long stored, recentup, recentdn;
                    for (int i = idxhigh; i <= idxlow; ++i)
                    {
                        stored = vprofile[i];
                        if ((!useprevsession) && (i >= idxcbarh) && (i <= idxcbarl))
                        {
                            edcbar.getUpDnTicksAtPrice(TickSize, dispmax - ((i - idxhigh) * TickSize), out recentup, out recentdn);
                            stored += (recentup + recentdn);
                        }
                        if (stored > maxvprof)
                        {
                            maxvprof = stored;
                        }
                    }

                    paintBrush.Color = sessionProfileColor;

                    var profY2 = ChartControl.GetYByValue(this, dispmax) - halfHeight;
                    for (int i = idxhigh; i <= idxlow; ++i)
                    {
                        var profY = profY2;
                        profY2 = ChartControl.GetYByValue(this, dispmax - (i - idxhigh + 1) * TickSize) - halfHeight;
                        if (profY2 > linlvl)
                        {
                            profY2 = linlvl;
                        }
                        if (profY == profY2)
                        {
                            continue;
                        }
                        stored = vprofile[i];
                        if ((!useprevsession) && (i >= idxcbarh) && (i <= idxcbarl))
                        {
                            edcbar.getUpDnTicksAtPrice(TickSize, dispmax - ((i - idxhigh) * TickSize), out recentup, out recentdn);
                            stored += (recentup + recentdn);
                        }
                        if (stored > 0)
                        {
                            graphics.FillRectangle(paintBrush, bounds.Left, profY, stored * (bounds.Width / 2) / maxvprof, profY2 - profY);
                        }
                    }
                }
            }
            #endregion dispvolprofile

            // now paint the tradedamounts, if needed....
            #region tradedamts
            if (displaytradedamounts && (lastBar == CurrentBar))
            {
                paintBrush.Color = neutcolor;
                lilrect.X        = ChartControl.GetXByBarIdx(BarsArray[0], lastBar) + barWidth;
                if (tradedPrices[0] > 0)
                {
                    lilrect.Y = ChartControl.GetYByValue(this, tradedPrices[0]) - halfHeight;
                    graphics.DrawString(tradedAmounts[0].ToString(), deltaFont, paintBrush, lilrect, rightFormat);
                }
                if (tradedPrices[1] > 0)
                {
                    lilrect.Y = ChartControl.GetYByValue(this, tradedPrices[1]) - halfHeight;
                    graphics.DrawString(tradedAmounts[1].ToString(), deltaFont, paintBrush, lilrect, rightFormat);
                }
            }
            #endregion tradedamts
        }