/// <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 (volume <= bars.Period.Value2) return;
			
			if (bars.Count == 0)
			{
				while (volume > bars.Period.Value)
				{
					AddBar(bars, open, high, low, close, time, bars.Period.Value, isRealtime);
					volume -= bars.Period.Value;
				}

				if (volume > 0)
					AddBar(bars, open, high, low, close, time, volume, isRealtime);
			}
			else
			{
				long volumeTmp = 0;
				if (!bars.IsNewSession(time, isRealtime))
				{
					volumeTmp = Math.Min(bars.Period.Value - bars.GetVolume(bars.Count - 1), volume);
					if (volumeTmp > 0)
						UpdateBar(bars, open, high, low, close, time, volumeTmp, isRealtime);
				}

				volumeTmp = volume - volumeTmp;
				while (volumeTmp > 0)
				{
					AddBar(bars, open, high, low, close, time, Math.Min(volumeTmp, bars.Period.Value), isRealtime);
					volumeTmp -= bars.Period.Value;
				}
			}
		}
示例#2
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);
            }

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

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

            long barsPeriodValue = bars.BarsPeriod.Value;

            if (bars.Instrument.MasterInstrument.InstrumentType == InstrumentType.CryptoCurrency)
            {
                barsPeriodValue = Core.Globals.FromCryptocurrencyVolume(bars.BarsPeriod.Value);
            }

            if (bars.Count == 0)
            {
                while (volume > barsPeriodValue)
                {
                    AddBar(bars, open, high, low, close, time, barsPeriodValue);
                    volume -= barsPeriodValue;
                }
                if (volume > 0)
                {
                    AddBar(bars, open, high, low, close, time, volume);
                }
            }
            else
            {
                long volumeTmp = 0;
                if (!bars.IsResetOnNewTradingDay || !isNewSession)
                {
                    volumeTmp = Math.Min(barsPeriodValue - bars.GetVolume(bars.Count - 1), volume);
                    if (volumeTmp > 0)
                    {
                        UpdateBar(bars, high, low, close, time, volumeTmp);
                    }
                }

                volumeTmp = volume - volumeTmp;
                while (volumeTmp > 0)
                {
                    AddBar(bars, open, high, low, close, time, Math.Min(volumeTmp, barsPeriodValue));
                    volumeTmp -= barsPeriodValue;
                }
            }
        }
        /// <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 (volume <= bars.Period.Value2)
            {
                return;
            }

            if (bars.Count == 0)
            {
                while (volume > bars.Period.Value)
                {
                    AddBar(bars, open, high, low, close, time, bars.Period.Value, isRealtime);
                    volume -= bars.Period.Value;
                }

                if (volume > 0)
                {
                    AddBar(bars, open, high, low, close, time, volume, isRealtime);
                }
            }
            else
            {
                long volumeTmp = 0;
                if (!bars.IsNewSession(time, isRealtime))
                {
                    volumeTmp = Math.Min(bars.Period.Value - bars.GetVolume(bars.Count - 1), volume);
                    if (volumeTmp > 0)
                    {
                        UpdateBar(bars, open, high, low, close, time, volumeTmp, isRealtime);
                    }
                }

                volumeTmp = volume - volumeTmp;
                while (volumeTmp > 0)
                {
                    AddBar(bars, open, high, low, close, time, Math.Min(volumeTmp, bars.Period.Value), isRealtime);
                    volumeTmp -= bars.Period.Value;
                }
            }
        }
示例#4
0
        public override double GetPercentComplete(Bars bars, DateTime now)
        {
            switch (BarsPeriod.BaseBarsPeriodType)
            {
            case BarsPeriodType.Day:       return(now.Date <= bars.LastBarTime.Date
                                                                                                                        ? 1.0 - bars.LastBarTime.AddDays(1).Subtract(now).TotalDays / bars.BarsPeriod.BaseBarsPeriodValue
                                                                                                                        : 1);

            case BarsPeriodType.Minute:       return(now <= bars.LastBarTime ? 1.0 - bars.LastBarTime.Subtract(now).TotalMinutes / bars.BarsPeriod.BaseBarsPeriodValue : 1);

            case BarsPeriodType.Month:
                if (now.Date <= bars.LastBarTime.Date)
                {
                    int month       = now.Month;
                    int daysInMonth = month == 2 ? (DateTime.IsLeapYear(now.Year) ? 29 : 28) : (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 ? 31 : 30);
                    return((daysInMonth - bars.LastBarTime.Date.AddDays(1).Subtract(now).TotalDays / bars.BarsPeriod.BaseBarsPeriodValue) / daysInMonth);
                }
                return(1);

            case BarsPeriodType.Second:       return(now <= bars.LastBarTime ? 1.0 - bars.LastBarTime.Subtract(now).TotalSeconds / bars.BarsPeriod.BaseBarsPeriodValue : 1);

            case BarsPeriodType.Tick:       return((double)bars.TickCount / bars.BarsPeriod.BaseBarsPeriodValue);

            case BarsPeriodType.Volume:       return(bars.Count == 0 ? 0 : (double)bars.GetVolume(bars.Count - 1) / bars.BarsPeriod.BaseBarsPeriodValue);

            case BarsPeriodType.Week:       return(now.Date <= bars.LastBarTime.Date ? (7 - bars.LastBarTime.AddDays(1).Subtract(now).TotalDays / bars.BarsPeriod.BaseBarsPeriodValue) / 7 : 1);

            case BarsPeriodType.Year:
                if (now.Date <= bars.LastBarTime.Date)
                {
                    double daysInYear = DateTime.IsLeapYear(now.Year) ? 366 : 365;
                    return((daysInYear - bars.LastBarTime.Date.AddDays(1).Subtract(now).TotalDays / bars.BarsPeriod.BaseBarsPeriodValue) / daysInYear);
                }
                return(1);

            default: return(1);
            }
        }
示例#5
0
        //
        protected override void OnBarUpdate()
        {
            double currentBarSize = (float)Math.Abs(Open[0] - Close[0]);

            if (CurrentBar > 2)
            {
                //
                if (Int32.Parse(MyStopW.ElapsedTime) >= 5)
                {
                    long volumeValue = Bars.GetVolume(CurrentBar);
                    //
                    if (volumeValue >= volumenTarget && currentBarSize >= candleSize)
                    {
                        //
                        if (emailSent == false && CurrentBar != emailBar)
                        {
                            emailSent = true;
                            emailBar  = CurrentBar;
                            string filePath = pathAssembler(CurrentBar.ToString());
                            SaveScreenShot(filePath);
                            //
                            string message = string.Format("- Alert!!! The volume of the current bar is above target, current bar volumen of {0} and bar size of {1}",
                                                           volumeValue.ToString(), currentBarSize.ToString());
                            string subject = "Nestor Colt Informatic Trading Solutions";
                            // Send email :
                            Thread.Sleep(1000);
                            Sender.composeMessage("*****@*****.**", Email, subject, message, filePath);
                            Print("Email Sent");
                        }
                    }
                    else if (volumeValue < 50 && CurrentBar != emailBar)
                    {
                        emailSent = false;
                    }
                }
            }
        }
示例#6
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;
        }
示例#7
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;
            }
        }
示例#8
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
		}
示例#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);
            }

            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;
        }
示例#10
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;
        }
示例#11
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);
                    }
                }
            }
        }
示例#12
0
        protected override void OnBarUpdate()
        {
            // Get time of first bar on chart
            if (isFirstChartBar)
            {
                isFirstChartBar = false;
                chartStartTime  = Time[0];
            }

            // Not Enough History to calc rel vol
            if (Time[0].Date.AddDays(LookBackDays * -1) < chartStartTime.Date)
            {
                return;
            }

            // Only gather vol history on first tick
            // of bar since history does not change for
            // a given bar
            if (IsFirstTickOfBar)
            {
                int skipDays = 0;
                totalHistPeriodVol = 0;
                histPeriodVol      = new List <double>(LookBackDays);

                // Loop until all same timeperiod lookback days
                // are found or lookback exceeds history
                while (histPeriodVol.Count < LookBackDays)
                {
                    // Bar target time
                    DateTime tt = Time[0].AddDays((histPeriodVol.Count + 1 + skipDays) * -1);

                    // Bail if target day is before first chart, not enough history
                    if (tt.Date < Time[CurrentBar].Date)
                    {
                        return;
                    }

                    // No weekends
                    if ((tt.DayOfWeek == DayOfWeek.Saturday) || (tt.DayOfWeek == DayOfWeek.Sunday))
                    {
                        skipDays++;
                        continue;
                    }

                    // Skip over early close days and Holidays
                    if (TradingHours.PartialHolidays.ContainsKey(tt.Date) ||
                        TradingHours.Holidays.ContainsKey(tt.Date))
                    {
                        skipDays++;
                        continue;
                    }

                    // Get Prev day's same time bar
                    int relPrevBar = ChartBars.GetBarIdxByTime(ChartControl, tt);

                    // If the returned bar is not the expected date, a bar with the
                    // timetarget is not on the chart.  Dont know why GetBarIdxByTime
                    // does not return something more normal(like a -1) for a GetBarIdxXXX()
                    // miss.  Instead it just returns the incorrect bar.
                    // At this point a missing bar is unexpected
                    if (tt != Bars.GetTime(relPrevBar))
                    {
                        throw new Exception("Missing data error - Target Time: " + tt + " Found Time: " + Bars.GetTime(relPrevBar));
                    }

                    totalHistPeriodVol += Bars.GetVolume(relPrevBar);
                    histPeriodVol.Add(Bars.GetVolume(relPrevBar));
                }
                histPeriodVolStd = this.getStandardDeviation(histPeriodVol);
                avgHistPeriodVol = totalHistPeriodVol / LookBackDays;
            }

            // Get historical average at time volume from last x days
            Values[3][0] = avgHistPeriodVol;

            // Difference between avg period vol and current bars vol
            double rel_vol_diff = Volume[0] - avgHistPeriodVol;

            // Std Hi-Low Hash marks
            Values[1][0] = Math.Max(0.0, avgHistPeriodVol - histPeriodVolStd);
            Values[2][0] = avgHistPeriodVol + histPeriodVolStd;

            // Raw period volume bars, color code based on
            // volume above, below or within 1 std band
            Values[0][0] = Volume[0];
            if (ShowVolumeBars)
            {
                // Greater than one std
                if (Volume[0] > Values[2][0])
                {
                    PlotBrushes[0][0] = VolAboveStdBrush;
                }
                // Within one std
                else if (Values[0][0] > Values[1][0])
                {
                    PlotBrushes[0][0] = VolWithinStdBrush;
                }
                // Less than 1 std
                else
                {
                    PlotBrushes[0][0] = VolBelowStdBrush;
                }
            }
            else
            {
                PlotBrushes[0][0] = Brushes.Transparent;
            }
        }
示例#13
0
        public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars)
        {
            Bars       bars          = chartBars.Bars;
            Vector2    point0        = new Vector2();
            Vector2    point1        = new Vector2();
            RectangleF rect          = new RectangleF();
            float      maxHalfWidth  = (GetBarPaintWidth(BarWidthUI) - 1) / 2;
            float      maxMeanAvgVol = 0;

            for (int idx = chartBars.FromIndex; idx < chartBars.ToIndex; idx++)
            {
                float meanAvg = (bars.GetVolume(idx) + bars.GetVolume(idx + 1)) / 2;
                if (meanAvg > maxMeanAvgVol)
                {
                    maxMeanAvgVol = meanAvg;
                }
            }

            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));
                float  barWidth  = 1 + (2 * (float)Math.Round(bars.GetVolume(idx) / maxMeanAvgVol * maxHalfWidth));
                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);
                }
            }
        }
示例#14
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;
        }
示例#15
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;
		}
        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);
            }
            bool isNewSession = SessionIterator.IsNewSession(time, isBar);

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

            #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 = anchorPrice = bars.GetClose(bars.Count - 1);
                }
            }

            switch (BarsPeriod.BaseBarsPeriodType)
            {
            case BarsPeriodType.Day:
                tmpTime = time.Date;
                if (!isBar)
                {
                    tmpDayCount++;
                    if (tmpTime < time.Date)
                    {
                        tmpTime = time.Date;                                                  // Make sure timestamps are ascending
                    }
                }

                if (isBar && prevTimeD != tmpTime)
                {
                    tmpDayCount++;
                }

                if (isBar && bars.Count > 0 && tmpTime == bars.LastBarTime.Date ||
                    !isBar && bars.Count > 0 && tmpTime <= bars.LastBarTime.Date ||
                    tmpDayCount < BarsPeriod.BaseBarsPeriodValue)
                {
                    endOfBar = false;
                }
                else
                {
                    prevTime  = prevTimeD == Core.Globals.MinDate ? tmpTime : prevTimeD;
                    prevTimeD = 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 >= BarsPeriod.BaseBarsPeriodValue;
                    prevTime  = tmpTime = time;
                    if (endOfBar)
                    {
                        tmpVolume = 0;
                    }
                    break;
                }

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

            case BarsPeriodType.Month:
                if (tmpTime == Core.Globals.MinDate)
                {
                    prevTime = tmpTime = TimeToBarTimeMonth(time, 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, BarsPeriod.BaseBarsPeriodValue);
                }
                break;

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

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

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

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

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

            if (bars.Count == 0 || IsIntraday && bars.IsResetOnNewTradingDay && isNewSession)
            {
                if (bars.Count > 0)
                {
                    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, lastHigh, lastLow, lastClose, prevTime == Core.Globals.MinDate ? time : prevTime, lastTime);
                    }
                }

                AddBar(bars, close, close, close, close, tmpTime, volume);

                anchorPrice    = close;
                trend          = Trend.Undetermined;
                prevTime       = tmpTime;
                volumeCount    = 0;
                bars.LastPrice = close;
                tmpCount       = bars.Count;
                tmpHigh        = high;
                tmpLow         = low;
                return;
            }

            double   c = bars.GetClose(bars.Count - 1);
            double   h = bars.GetHigh(bars.Count - 1);
            double   l = bars.GetLow(bars.Count - 1);
            DateTime t = bars.GetTime(bars.Count - 1);

            if (endOfBar)
            {
                CalculatePfBar(bars, h, l, c, prevTime, t);
                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
        }
示例#17
0
 public override double GetPercentComplete(Bars bars, DateTime now)
 {
     return(bars.Count == 0 ? 0 : (double)bars.GetVolume(bars.Count - 1) / bars.BarsPeriod.Value);
 }
示例#18
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;
        }
示例#19
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:
                if (bars.Count == 0)
                {
                    if (isRealtime && bars.Session.SessionsOfDay.Length > 0)
                    {
                        DateTime barTime;
                        bars.Session.GetSessionDate(time, false, out barTime, out cacheSessionEnd);
                        AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, barTime, volume, true);
                    }
                    else
                    {
                        AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time.Date, volume, isRealtime);
                    }
                }
                else
                {
                    DateTime barTime;
                    if (!isRealtime)
                    {
                        barTime = time.Date;
                    }
                    else if (time >= cacheSessionEnd /* on realtime include60 is always false */)
                    {
                        bars.Session.GetSessionDate(time, false, out barTime, out cacheSessionEnd);
                        if (barTime < bars.TimeLastBar.Date)
                        {
                            barTime = bars.TimeLastBar.Date;     // make sure timestamps are ascending
                        }
                    }
                    else
                    {
                        barTime = bars.TimeLastBar.Date;     // make sure timestamps are ascending
                    }
                    if (bars.DayCount < bars.Period.Value ||
                        (!isRealtime && bars.Count > 0 && barTime == bars.TimeLastBar.Date) ||
                        (isRealtime && bars.Count > 0 && barTime <= bars.TimeLastBar.Date))
                    {
                        UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, barTime, volume, isRealtime);
                    }
                    else
                    {
                        AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, barTime, volume, isRealtime);
                    }
                }

                break;

            case PeriodType.Minute:
                if (bars.Count == 0)
                {
                    AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, TimeToBarTimeMinute(bars, time, bars.Session.NextBeginTime, bars.Period.Value, isRealtime), volume, isRealtime);
                }
                else
                {
                    if (isRealtime && time < bars.TimeLastBar)
                    {
                        UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, bars.TimeLastBar, volume, true);
                    }
                    else if (!isRealtime && time <= bars.TimeLastBar)
                    {
                        UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, bars.TimeLastBar, volume, false);
                    }
                    else
                    {
                        time = TimeToBarTimeMinute(bars, time, bars.Session.NextBeginTime, bars.Period.Value, isRealtime);
                        AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, volume, isRealtime);
                    }
                }
                break;

            case PeriodType.Volume:
                if (bars.Count == 0)
                {
                    while (volume > bars.Period.Value)
                    {
                        AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, bars.Period.Value, isRealtime);
                        volume -= bars.Period.Value;
                    }

                    if (volume > 0)
                    {
                        AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, volume, isRealtime);
                    }
                }
                else
                {
                    long volumeTmp = 0;
                    if (!bars.IsNewSession(time, isRealtime))
                    {
                        volumeTmp = Math.Min(bars.Period.Value - bars.GetVolume(bars.Count - 1), volume);
                        if (volumeTmp > 0)
                        {
                            UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, volumeTmp, isRealtime);
                        }
                    }

                    volumeTmp = volume - volumeTmp;
                    while (volumeTmp > 0)
                    {
                        AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, Math.Min(volumeTmp, bars.Period.Value), isRealtime);
                        volumeTmp -= bars.Period.Value;
                    }
                }
                break;

            case PeriodType.Month:
                if (bars.Count == 0)
                {
                    AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, TimeToBarTimeMonth(time, bars.Period.Value), volume, isRealtime);
                }
                else
                {
                    if ((time.Month <= bars.TimeLastBar.Month && time.Year == bars.TimeLastBar.Year) || time.Year < bars.TimeLastBar.Year)
                    {
                        UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, bars.TimeLastBar, volume, isRealtime);
                    }
                    else
                    {
                        AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, TimeToBarTimeMonth(time, bars.Period.Value), volume, isRealtime);
                    }
                }
                break;

            case PeriodType.Second:
                if (bars.Count == 0)
                {
                    AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, 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.Value), volume, isRealtime);
                }
                else
                {
                    if ((bars.Period.Value > 1 && time < bars.TimeLastBar) ||
                        (bars.Period.Value == 1 && time <= bars.TimeLastBar))
                    {
                        UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, bars.TimeLastBar, volume, isRealtime);
                    }
                    else
                    {
                        time = TimeToBarTimeSecond(bars, time, bars.Session.NextBeginTime, bars.Period.Value);
                        AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, volume, isRealtime);
                    }
                }
                break;

            case PeriodType.Tick:
                if (bars.Count == 0)
                {
                    AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, volume, isRealtime);
                }
                else
                {
                    if (bars.Count > 0 && !bars.IsNewSession(time, isRealtime) && bars.Period.Value > 1 && bars.TickCount < bars.Period.Value)
                    {
                        UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, volume, isRealtime);
                    }
                    else
                    {
                        AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, volume, isRealtime);
                    }
                }
                break;

            case PeriodType.Week:
                if (bars.Count == 0)
                {
                    AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, TimeToBarTimeWeek(time, time.AddDays((6 - (((int)time.DayOfWeek + 1) % 7)) + ((bars.Period.Value - 1) * 7)), bars.Period.Value), volume, isRealtime);
                }
                else if (time.Date <= bars.TimeLastBar.Date)
                {
                    UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, bars.TimeLastBar, volume, isRealtime);
                }
                else
                {
                    AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, TimeToBarTimeWeek(time.Date, bars.TimeLastBar.Date, bars.Period.Value), volume, isRealtime);
                }
                break;

            case PeriodType.Year:
                if (bars.Count == 0)
                {
                    AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, TimeToBarTimeYear(time, bars.Period.Value), volume, isRealtime);
                }
                else
                {
                    if (time.Year <= bars.TimeLastBar.Year)
                    {
                        UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, bars.TimeLastBar, volume, isRealtime);
                    }
                    else
                    {
                        AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, TimeToBarTimeYear(time.Date, bars.Period.Value), volume, isRealtime);
                    }
                }
                break;

            default:
                break;
            }
            #endregion
        }
示例#20
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
        }
示例#21
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();
        }
示例#22
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
		}