public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime)
        {
            //### First Bar
            if ((bars.Count == 0) || bars.IsNewSession(time, isRealtime))
            {
                tickSize = bars.Instrument.MasterInstrument.TickSize;

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

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

                AddBar(bars, barOpen, barOpen, barOpen, barOpen, time, volume, isRealtime);
            }
            //### Subsequent Bars
            else
            {
                Data.Bar bar = (Bar)bars.Get(bars.Count - 1);
                maxExceeded = bars.Instrument.MasterInstrument.Compare(close, barMax) > 0 ? true : false;
                minExceeded = bars.Instrument.MasterInstrument.Compare(close, barMin) < 0 ? true : false;

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

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

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

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

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

            bars.LastPrice = close;
        }
        /// <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 ((curdat == null) || (time < curdat.dt))
            {
                extdat.Clear();
                extdat.TrimExcess();
                curdat   = null;
                tickSize = bars.Instrument.MasterInstrument.TickSize;
            }
            if (bars.Count == 0)
            {
                AddBar(bars, open, high, low, close, time.Date, volume, isRealtime);
                RWTAddExtDat(time, close, volume);
            }
            else
            {
                if (curdat == null)
                {
                    RWTAddExtDat(time, close, 0);
                }
                Bar bar = (Bar)bars.Get(bars.Count - 1);

                double tall  = 1 + ((bar.High - bar.Low) / bars.Instrument.MasterInstrument.TickSize);
                double denom = tall;

                if (tall < 2)
                {
                    denom += 99999;
                }
                if (tall > 10)
                {
                    denom -= ((tall - 10) / 2.0);
                }
                if (tall > 20)
                {
                    denom -= ((tall - 20) / 3.0);
                }
                if (((double)(bar.Volume + volume)) / denom >= ((double)(bars.Period.Value)))
                {
                    AddBar(bars, close, close, close, close, time, volume, isRealtime);
                    RWTAddExtDat(time, close, volume);
                }
                else
                {
                    UpdateBar(bars, open, high, low, close, time, volume, isRealtime);
                    curdat.dt = time;
                    RWTUpdateCurdat(close, volume);
                }
            }
            bars.LastPrice = close;
            prevClose      = close;
        }
        /// <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 ((curdat == null) || (time < curdat.dt))
            {
                extdat.Clear();
                extdat.TrimExcess();
                curdat   = null;
                tickSize = bars.Instrument.MasterInstrument.TickSize;
            }
            if (bars.Count == 0)
            {
                AddBar(bars, open, high, low, close, time, volume, isRealtime);
                RWTAddExtDat(time, close, volume);
            }
            else
            {
                Data.Bar bar = (Bar)bars.Get(bars.Count - 1);
                if (curdat == null)
                {
                    RWTAddExtDat(time, close, 0);
                }
                curdat.dt = time;
                if (upbar && ((curdat.dHigh - curdat.dClose) >= bars.Period.Value))
                {
                    AddBar(bars, close, close, close, close, time, volume, isRealtime);
                    RWTAddExtDat(time, close, volume);
                    upbar = false;
                }
                else if (!upbar && ((curdat.dClose - curdat.dLow) >= bars.Period.Value))
                {
                    AddBar(bars, close, close, close, close, time, volume, isRealtime);
                    RWTAddExtDat(time, close, volume);
                    upbar = true;
                }
                else
                {
                    UpdateBar(bars, open, high, low, close, time, volume, isRealtime); // regular update...
                    RWTUpdateCounts(close);
                    RWTUpdateCurdat(close, volume);
                }
            }
            bars.LastPrice = close;

            // update the extended data...
            prevClose = close;
        }
Beispiel #4
0
        protected override void OnBarUpdate()
        {
            if (Bars == null)
            {
                return;
            }
            if (!BarsType.GetInstance(Bars.Period.Id).IsIntraday)
            {
                return;
            }
            if (Bars.Period.Id == PeriodType.Minute && Bars.Period.Value > _minutes / 2)
            {
                return;
            }

            if (!_isLoaded && !_isInit)
            {
                _isInit               = true;
                _intradayBars         = Bars.GetBars(Bars.Instrument, new Period(PeriodType.Minute, _minutes, MarketDataType.Last), Bars.From, Bars.To, (Session)Bars.Session.Clone(), Bars.SplitAdjust, Bars.DividendAdjust);
                _existsHistHourlyData = (_intradayBars.Count <= 1) ? false : true;
                _isInit               = false;
                _isLoaded             = true;
            }

            if (!_existsHistHourlyData)
            {
                return;
            }

            DateTime intradayBarTime = Time[0].AddMinutes(-_minutes);
            IBar     intradayBar     = _intradayBars.Get(_intradayBars.GetBar(intradayBarTime));
            double   high            = intradayBar.High;
            double   low             = intradayBar.Low;
            double   close           = intradayBar.Close;

            Hpp.Set((high + low + close) / 3);
            Hs1.Set(2 * Hpp[0] - high);
            Hr1.Set(2 * Hpp[0] - low);
            Hs2.Set(Hpp[0] - (high - low));
            Hr2.Set(Hpp[0] + (high - low));
        }
Beispiel #5
0
        public override double GetPercentComplete(Bars bars, DateTime now)
        {
            switch (Period.BasePeriodType)
            {
            case PeriodType.Day: return(now.Date <= bars.TimeLastBar.Date ? 1.0 - (bars.TimeLastBar.AddDays(1).Subtract(now).TotalDays / bars.Period.Value) : 1);

            case PeriodType.Minute: return(now <= bars.TimeLastBar ? 1.0 - (bars.TimeLastBar.Subtract(now).TotalMinutes / bars.Period.Value) : 1);

            case PeriodType.Month:
                if (now.Date <= bars.TimeLastBar.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.TimeLastBar.Date.AddDays(1).Subtract(now).TotalDays / bars.Period.Value)) /
                           daysInMonth);                // not exact
                }
                return(1);

            case PeriodType.Second: return(now <= bars.TimeLastBar ? 1.0 - (bars.TimeLastBar.Subtract(now).TotalSeconds / bars.Period.Value) : 1);

            case PeriodType.Tick: return((double)bars.TickCount / bars.Period.Value);

            case PeriodType.Volume: return((double)bars.Get(bars.CurrentBar).Volume / bars.Period.Value);

            case PeriodType.Week: return(now.Date <= bars.TimeLastBar.Date ? (7 - (bars.TimeLastBar.AddDays(1).Subtract(now).TotalDays / bars.Period.Value)) / 7 : 1);

            case PeriodType.Year:
                if (now.Date <= bars.TimeLastBar.Date)
                {
                    double daysInYear = DateTime.IsLeapYear(now.Year) ? 366 : 365;
                    return((daysInYear - (bars.TimeLastBar.Date.AddDays(1).Subtract(now).TotalDays / bars.Period.Value)) /
                           daysInYear);
                }
                return(1);

            default: return(now.Date <= bars.TimeLastBar.Date ? 1.0 - (bars.TimeLastBar.AddDays(1).Subtract(now).TotalDays / bars.Period.Value) : 1);
            }
        }
Beispiel #6
0
        /// <summary>
        /// Called on each incoming tick
        /// </summary>
        void OnTick(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime)
        {
            // ensure xml config loaded
            ConfigCheck();

            // create initial bar on first tick and handle NT7 session-break issue (note: removing IsNewSession() creates invalid bars; remove if preferred)
            if ((bars.Count == 0) || bars.IsNewSession(time, isRealtime))
            {
                // set class fields
                tickSize = bars.Instrument.MasterInstrument.TickSize;

                // calculate bear/bull min/max
                RangeInit();

                // update class fields
                AdjustOpenClose(bars, close, close);
                prevClose = close;

                // add first bar
                AddBar(bars, thisOpen, thisOpen, thisOpen, thisOpen, time, volume, isRealtime);

                // add EmProps
                AddEmProps(thisOpen, volume, thisCloseDown, thisCloseUp, time);
            }

            // continue all subsequent ticks/bars
            else
            {
                // local variables
                Bar bar              = (Bar)bars.Get(bars.Count - 1);
                int compareCloseUp   = bars.Instrument.MasterInstrument.Compare(close, thisCloseUp);
                int compareCloseDown = bars.Instrument.MasterInstrument.Compare(close, thisCloseDown);

                // range exceeded; create new bar(s)
                if (((compareCloseUp > 0 || compareCloseDown < 0) && CloseOption == EmCloses.TickThru) || ((compareCloseUp >= 0 || compareCloseDown <= 0) && CloseOption == EmCloses.OnTouch))
                {
                    // local variables
                    bool   newBar    = true;
                    double thisClose = (compareCloseUp > 0) ? Math.Min(close, thisCloseUp) : (compareCloseDown < 0) ? Math.Max(close, thisCloseDown) : close;

                    // close current bar; volume included for on-touch only
                    // see this post for more info on volume calculation: http://www.ninjatrader.com/support/forum/showthread.php?p=302208#post302208
                    UpdateBar(bars, bar.Open, ((compareCloseUp > 0) ? thisClose : bar.High), ((compareCloseDown < 0) ? thisClose : bar.Low), thisClose, time, ((CloseOption == EmCloses.OnTouch) ? volume : 0), isRealtime);
                    barProps.Finalize(thisClose, prevClose, ((CloseOption == EmCloses.OnTouch) ? volume : 0), time, ((close > bar.Open) ? 1 : (close < bar.Open) ? -1 : 0));

                    // add next bar and loop phantom bars, if needed
                    do
                    {
                        // update class fields
                        thisBias  = (close > bar.Open) ? 1 : (close < bar.Open) ? -1 : 0;
                        tickRange = EmMath.RangeValidate(Math.Abs(AddTwoDoubles(bars, bar.Open, -thisClose)), (thisBias == -1) ? tickBearRangeMax : tickBullRangeMax, (thisBias == -1) ? tickBearRangeMin : tickBullRangeMin);
                        AdjustOpenClose(bars, thisClose, close);
                        thisClose = (compareCloseUp > 0) ? Math.Min(close, thisCloseUp) : (compareCloseDown < 0) ? Math.Max(close, thisCloseDown) : close;

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

                        // add EmProps
                        AddEmProps(thisOpen, ((compareCloseUp > 0) ? thisClose : thisOpen), ((compareCloseDown < 0) ? thisClose : thisOpen), thisClose, ((CloseOption == EmCloses.TickThru && newBar) ? volume : 0), time, thisBias, thisCloseDown, thisCloseUp);

                        // update class fields
                        newBar           = false;
                        compareCloseUp   = bars.Instrument.MasterInstrument.Compare(close, thisCloseUp);
                        compareCloseDown = bars.Instrument.MasterInstrument.Compare(close, thisCloseDown);
                    }while (((compareCloseUp > 0 || compareCloseDown < 0) && CloseOption == EmCloses.TickThru) || ((compareCloseUp >= 0 || compareCloseDown <= 0) && CloseOption == EmCloses.OnTouch));
                }

                // range not exceeded; continue current bar
                else
                {
                    // update current bar
                    UpdateBar(bars, bar.Open, ((close > bar.High) ? close : bar.High), ((close < bar.Low) ? close : bar.Low), close, time, volume, isRealtime);

                    // update EmProps
                    barProps.Update(close, prevClose, volume, time);
                }
            }

            // update prevClose and last price
            bars.LastPrice = prevClose = close;
        }
Beispiel #7
0
        // Override OnBarUpdate method
        protected override void OnBarUpdate()
        {
            // Protect against too few bars
            if (Bars == null)
            {
                return;
            }
            if (!Data.BarsType.GetInstance(Bars.Period.Id).IsIntraday)
            {
                return;
            }
            if (Bars.Period.Id == PeriodType.Minute && Bars.Period.Value > timeFrame / 2)
            {
                return;
            }
            if (!full && !apt)
            {
                apt        = true;
                periodBars = Data.Bars.GetBars(Bars.Instrument, new Period(PeriodType.Minute, timeFrame, MarketDataType.Last), Bars.From, Bars.To, (Session)Bars.Session.Clone(), Data.Bars.SplitAdjust, Data.Bars.DividendAdjust);
                apt        = false;
                full       = true;
            }

            // Remove calculation for first time span after open
            IBar periodBar;

            Bars.Session.GetNextBeginEnd(Time[0], out sessionBegin, out sessionEnd);
            if (Time[0] >= sessionBegin && Time[0] <= sessionBegin.AddMinutes(timeFrame))
            {
                Pivot.Reset();
                Resistance1.Reset();
                Support1.Reset();
                Resistance2.Reset();
                Support2.Reset();
                Resistance3.Reset();
                Support3.Reset();
                Resistance4.Reset();
                Support4.Reset();
                Resistance5.Reset();
                Support5.Reset();
            }
            else
            {
                // Determine open, high, low, and close
                DateTime intradayBarTime = Time[0].AddMinutes(-timeFrame);
                periodBar = periodBars.Get(periodBars.GetBar(intradayBarTime));
                double Open  = periodBar.Open;
                double High  = periodBar.High;
                double Low   = periodBar.Low;
                double Close = periodBar.Close;
                double pivot = periodBar.Close;

                // Switch central pivot calculation
                switch (centralPivotCalculation)
                {
                // Standard calculation case
                case CentralPivotCalculation.Standard:
                {
                    pivot = (High + Low + Close) / 3;
                    break;
                }

                // Open included calculation case
                case CentralPivotCalculation.OpenIncluded:
                {
                    pivot = (Open + High + Low + Close) / 4;
                    break;
                }

                // Close weighted calculation case
                case CentralPivotCalculation.CloseWeighted:
                {
                    pivot = (High + Low + Close + Close) / 4;
                    break;
                }

                // High weighted calculation case
                case CentralPivotCalculation.HighWeighted:
                {
                    pivot = (High + High + Low + Close) / 4;
                    break;
                }

                // Low weighted calculation case
                case CentralPivotCalculation.LowWeighted:
                {
                    pivot = (High + Low + Low + Close) / 4;
                    break;
                }
                }

                // Switch round to tick option
                switch (roundToTick)
                {
                // Rounding case
                case RoundToTick.Yes:
                {
                    // Set all additional pivots, rounded
                    Pivot.Set(Instrument.MasterInstrument.Round2TickSize(pivot));
                    Resistance1.Set(Instrument.MasterInstrument.Round2TickSize(2 * Pivot[0] - Low));
                    Support1.Set(Instrument.MasterInstrument.Round2TickSize(2 * Pivot[0] - High));
                    Resistance2.Set(Instrument.MasterInstrument.Round2TickSize(Pivot[0] + (High - Low)));
                    Support2.Set(Instrument.MasterInstrument.Round2TickSize(Pivot[0] - (High - Low)));
                    Resistance3.Set(Instrument.MasterInstrument.Round2TickSize(High + 2 * (Pivot[0] - Low)));
                    Support3.Set(Instrument.MasterInstrument.Round2TickSize(Low - 2 * (High - Pivot[0])));
                    Resistance4.Set(Instrument.MasterInstrument.Round2TickSize(Pivot[0] + 2 * (High - Low)));
                    Support4.Set(Instrument.MasterInstrument.Round2TickSize(Pivot[0] - 2 * (High - Low)));
                    Resistance5.Set(Instrument.MasterInstrument.Round2TickSize(2 * (Pivot[0] + High) - 3 * Low));
                    Support5.Set(Instrument.MasterInstrument.Round2TickSize(2 * (Pivot[0] + Low) - 3 * High));
                    break;
                }

                // No rounding case
                case RoundToTick.No:
                {
                    // Set all additional pivots, not rounded
                    Pivot.Set(pivot);
                    Resistance1.Set(2 * Pivot[0] - Low);
                    Support1.Set(2 * Pivot[0] - High);
                    Resistance2.Set(Pivot[0] + (High - Low));
                    Support2.Set(Pivot[0] - (High - Low));
                    Resistance3.Set(High + 2 * (Pivot[0] - Low));
                    Support3.Set(Low - 2 * (High - Pivot[0]));
                    Resistance4.Set(Pivot[0] + 2 * (High - Low));
                    Support4.Set(Pivot[0] - 2 * (High - Low));
                    Resistance5.Set(2 * (Pivot[0] + High) - 3 * Low);
                    Support5.Set(2 * (Pivot[0] + Low) - 3 * High);
                    break;
                }
                }
            }
        }
		/// <summary>
		/// </summary>
		public override double GetPercentComplete(Bars bars, DateTime now)
		{
			return (double) bars.Get(bars.CurrentBar).Volume / bars.Period.Value;
		}
Beispiel #9
0
        public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime)
        {
            //	******************* ADDED FROM RENKO CODE TO SOLVE MEMORY LEAK	****************************
            // brick size is the trendOffset (Value) + openOffset (BasePeriodValue)
            offset = (bars.Period.Value + bars.Period.BasePeriodValue) * bars.Instrument.MasterInstrument.TickSize;

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


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

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

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

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


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

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


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

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

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

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

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


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

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

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



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

            bars.LastPrice = close;

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

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

					if (prevTime != tmpTime) tmpDayCount++;

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

					break;

				case PeriodType.Minute:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

			#endregion
		}
 /// <summary>
 /// </summary>
 public override double GetPercentComplete(Bars bars, DateTime now)
 {
     return((double)bars.Get(bars.CurrentBar).Volume / bars.Period.Value);
 }
Beispiel #12
0
        /// <summary>
        /// add new tick data to bars
        /// </summary>
        public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime)
        {
            // create initial bar on first tick and handle NT7 session-break issue (note: removing IsNewSession() creates invalid bars; remove if preferred)
            if ((bars.Count == 0) || bars.IsNewSession(time, isRealtime))
            {
                // update fields
                tickSize = bars.Instrument.MasterInstrument.TickSize;
                rangeMax = AddTwoDoubles(bars, (double)Period.Value * tickSize, 0);
                rangeMin = AddTwoDoubles(bars, (double)Period.BasePeriodValue * tickSize, 0);

                /// swap min/max if entered incorrectly
                if (rangeMin > rangeMax)
                {
                    double tmp = rangeMax;
                    rangeMax = rangeMin;
                    rangeMin = tmp;
                }

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

                // add first bar
                AddBar(bars, thisOpen, thisOpen, thisOpen, thisOpen, time, volume, isRealtime);
            }

            // continue all subsequent ticks/bars
            else
            {
                // local variables
                Data.Bar thisBar    = (Bar)bars.Get(bars.Count - 1);
                int      maxCompare = bars.Instrument.MasterInstrument.Compare(close, thisMax);
                int      minCompare = bars.Instrument.MasterInstrument.Compare(close, thisMin);
                double   thisClose  = maxCompare > 0 ? Math.Min(close, thisMax) : minCompare < 0 ? Math.Max(close, thisMin) : close;

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

                    // update bias
                    prevBias = thisBias;
                    thisBias = close > thisBar.Open ? 1 : close < thisBar.Open ? -1 : 0;

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

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

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

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

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

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

                        // update fields
                        maxCompare = bars.Instrument.MasterInstrument.Compare(close, thisMax);
                        minCompare = bars.Instrument.MasterInstrument.Compare(close, thisMin);
                    }while (maxCompare > 0 || minCompare < 0);
                }

                // range not exceeded; continue current bar
                else
                {
                    // update current bar
                    UpdateBar(bars, thisBar.Open, (close > thisBar.High ? close : thisBar.High), (close < thisBar.Low ? close : thisBar.Low), close, time, volume, isRealtime);
                }
            }

            // update last price
            bars.LastPrice = close;
        }
Beispiel #13
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;
		}
Beispiel #14
0
		/// <summary>
		/// </summary>
		/// <param name="bars"></param>
		/// <param name="open"></param>
		/// <param name="high"></param>
		/// <param name="low"></param>
		/// <param name="close"></param>
		/// <param name="time"></param>
		/// <param name="volume"></param>
		/// <param name="isRealtime"></param>
		public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime)
		{
			offset = bars.Period.Value * bars.Instrument.MasterInstrument.TickSize;

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

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

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

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

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

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

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

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

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

			bars.LastPrice	= close;
			tmpCount		= bars.Count;
		}
Beispiel #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 || bars.IsNewSession(time, isRealtime))
				AddBar(bars, open, high, low, close, time, volume, isRealtime);
			else
			{
				Bar			bar			= (Bar) bars.Get(bars.Count - 1); 
				double		tickSize	= bars.Instrument.MasterInstrument.TickSize;
				double		rangeValue	= Math.Floor(10000000.0 * bars.Period.Value * tickSize) / 10000000.0;

				if (bars.Instrument.MasterInstrument.Compare(close, bar.Low + rangeValue) > 0) 
				{
					bool	isFirstNewBar	= true;
					double	newClose		= bar.Low + rangeValue; // every bar closes either with high or low
                    if (bars.Instrument.MasterInstrument.Compare(bar.Close, newClose) < 0)
                        UpdateBar(bars, bar.Open, newClose, bar.Low, newClose, time, 0, isRealtime);

					// if still gap, fill with phantom bars
					double newBarOpen		= newClose + tickSize;
					while (bars.Instrument.MasterInstrument.Compare(close, newClose) > 0)
					{
						newClose			= Math.Min(close, newBarOpen + rangeValue);
						AddBar(bars, newBarOpen, newClose, newBarOpen, newClose, time, isFirstNewBar ? volume : 1, isRealtime);
						newBarOpen			= newClose + tickSize;
						isFirstNewBar		= false;
					}
				}
				else if (bars.Instrument.MasterInstrument.Compare(bar.High - rangeValue, close) > 0)
				{
					bool	isFirstNewBar	= true;
					double	newClose		= bar.High - rangeValue; // every bar closes either with high or low
                    if (bars.Instrument.MasterInstrument.Compare(bar.Close, newClose) > 0)
                        UpdateBar(bars, bar.Open, bar.High, newClose, newClose, time, 0, isRealtime);

					// if still gap, fill with phantom bars
					double newBarOpen = newClose - tickSize;
					while (bars.Instrument.MasterInstrument.Compare(newClose, close) > 0)
					{
						newClose		= Math.Max(close, newBarOpen - rangeValue);
						AddBar(bars, newBarOpen, newBarOpen, newClose, newClose, time, isFirstNewBar ? volume : 1, isRealtime);
						newBarOpen		= newClose - tickSize;
						isFirstNewBar	= false;
					}
				}
				else
					//UpdateBar(bars, open, high, low, close, time, volume, isRealtime);
					UpdateBar(bars, open, (close > bar.High ? close : bar.High), (close < bar.Low ? close : bar.Low), close, time, volume, isRealtime);
			}
			bars.LastPrice = close;
		}
Beispiel #16
0
        protected override void OnBarUpdate()
        {
            if (CurrentBars[0] < 121)
            {
                return;
            }
            if (Bars == null)
            {
                return;
            }
            if (!Data.BarsType.GetInstance(Bars.Period.Id).IsIntraday)
            {
                return;
            }
            if (Bars.Period.Id == PeriodType.Minute && Bars.Period.Value > minutes / 2)
            {
                return;
            }



            if (!isLoaded && !isInit)
            {
                isInit               = true;
                hourlyBars           = Data.Bars.GetBars(Bars.Instrument, new Period(PeriodType.Minute, minutes, MarketDataType.Last), Bars.From, Bars.To, (Session)Bars.Session.Clone(), Data.Bars.SplitAdjust, Data.Bars.DividendAdjust);
                existsHistHourlyData = (hourlyBars.Count <= 1) ? false : true;
                isInit               = false;
                isLoaded             = true;
            }
            IBar hourlyBar;

            if (CurrentBar == 0)
            {
                return;
            }
            if (existsHistHourlyData)
            {
                DateTime intradayBarTime = Time[0].AddMinutes(-minutes);
                hourlyBar = hourlyBars.Get(hourlyBars.GetBar(intradayBarTime));
                double high  = hourlyBar.High;
                double low   = hourlyBar.Low;
                double close = hourlyBar.Close;
                HPP.Set((high + low + close) / 3);
                if (HPP[0] != HPP[1])
                {
                    DrawRay("pp", true, 1, HPP[0], 0, HPP[0], Plots[0].Pen.Color, Plots[0].Pen.DashStyle, (int)Plots[0].Pen.Width);
                }
                HS1.Set(2 * HPP[0] - high);
                if (HS1[0] != HS1[1])
                {
                    DrawRay("hs1", true, 1, HS1[0], 0, HS1[0], Plots[1].Pen.Color, Plots[1].Pen.DashStyle, (int)Plots[1].Pen.Width);
                }
                HR1.Set(2 * HPP[0] - low);
                if (HR1[0] != HR1[1])
                {
                    DrawRay("hr1", true, 1, HR1[0], 0, HR1[0], Plots[4].Pen.Color, Plots[4].Pen.DashStyle, (int)Plots[4].Pen.Width);
                }
                HS2.Set(HPP[0] - (high - low));
                if (HS2[0] != HS2[1])
                {
                    DrawRay("hs2", true, 1, HS2[0], 0, HS2[0], Plots[2].Pen.Color, Plots[2].Pen.DashStyle, (int)Plots[2].Pen.Width);
                }
                HR2.Set(HPP[0] + (high - low));
                if (HR2[0] != HR2[1])
                {
                    DrawRay("hr2", true, 1, HR2[0], 0, HR2[0], Plots[5].Pen.Color, Plots[5].Pen.DashStyle, (int)Plots[5].Pen.Width);
                }
                HS3.Set(HS2[0] - (high - low));
                if (HS3[0] != HS3[1])
                {
                    DrawRay("hs3", true, 1, HS2[0], 0, HS2[0], Plots[3].Pen.Color, Plots[3].Pen.DashStyle, (int)Plots[3].Pen.Width);
                }
                HR3.Set(HR1[0] + (high - low));
                if (HR3[0] != HR3[1])
                {
                    DrawRay("hr3", true, 1, HR2[0], 0, HR2[0], Plots[6].Pen.Color, Plots[6].Pen.DashStyle, (int)Plots[6].Pen.Width);
                }
            }
            else
            {
                return;
            }
        }
Beispiel #17
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;
        }
        /// <summary>
        /// Called on each bar update event (incoming tick)
        /// </summary>
        protected override void OnBarUpdate()
        {
            if (Bars == null)
            {
                return;
            }
            if (!Bars.BarsType.IsIntraday && Bars.Period.Id != PeriodType.Day)
            {
                return;
            }
            if (Bars.Period.Id == PeriodType.Day && pivotRangeType == PivotRange.Daily)
            {
                return;
            }
            if (Bars.Period.Id == PeriodType.Day && Bars.Period.Value > 1)
            {
                return;
            }

            // pivots only work for
            // - intraday
            // - 1 day chart with PivotRange Weekly or Monthly

            if (!isDailyDataLoaded)
            {
                if (priorDayHLC == HLCCalculationMode.DailyBars && Bars.BarsType.IsIntraday)
                {
                    Enabled = false;
                    System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(GetBarsNow));
                    return;
                }

                existsHistDailyData = false;
                isDailyDataLoaded   = true;
            }

            IBar dailyBar;

            if (existsHistDailyData)
            {
                sessionDateDaily = GetLastBarSessionDate(Time[0], Bars, PivotRange.Daily);
                dailyBar         = dailyBars.Get(dailyBars.GetBar(sessionDateDaily));

                if (dailyBar.Time.Date > sessionDateDaily.Date)
                {
                    for (DateTime i = sessionDateDaily; i >= dailyBars.GetTime(0); i = i.AddDays(-1))
                    {
                        dailyBar = dailyBars.Get(dailyBars.GetBar(i));
                        if (dailyBar.Time.Date == i.Date)
                        {
                            break;
                        }
                    }
                }
            }
            else
            {
                dailyBar = null;
            }

            double high  = existsHistDailyData ? dailyBar.High : High[0];
            double low   = existsHistDailyData ? dailyBar.Low : Low[0];
            double close = existsHistDailyData ? dailyBar.Close : Close[0];

            DateTime lastBarTimeStamp = GetLastBarSessionDate(Time[0], Bars, pivotRangeType);

            if ((currentDate != Cbi.Globals.MinDate && pivotRangeType == PivotRange.Daily && lastBarTimeStamp != currentDate) ||
                (currentWeek != Cbi.Globals.MinDate && pivotRangeType == PivotRange.Weekly && lastBarTimeStamp != currentWeek) ||
                (currentMonth != Cbi.Globals.MinDate && pivotRangeType == PivotRange.Monthly && lastBarTimeStamp != currentMonth))
            {
                pp           = (currentHigh + currentLow + currentClose) / 3;
                s1           = 2 * pp - currentHigh;
                r1           = 2 * pp - currentLow;
                s2           = pp - (currentHigh - currentLow);
                r2           = pp + (currentHigh - currentLow);
                s3           = pp - 2 * (currentHigh - currentLow);
                r3           = pp + 2 * (currentHigh - currentLow);
                ppr1         = (pp + r1) / 2;
                pps1         = (pp + s1) / 2;
                r1r2         = (r1 + r2) / 2;
                s1s2         = (s1 + s2) / 2;
                r2r3         = (r2 + r3) / 2;
                s2s3         = (s2 + s3) / 2;
                currentClose = (priorDayHLC == HLCCalculationMode.UserDefinedValues) ? userDefinedClose : close;
                currentHigh  = (priorDayHLC == HLCCalculationMode.UserDefinedValues) ? userDefinedHigh : high;
                currentLow   = (priorDayHLC == HLCCalculationMode.UserDefinedValues) ? userDefinedLow : low;
            }
            else
            {
                currentClose = (priorDayHLC == HLCCalculationMode.UserDefinedValues) ? userDefinedClose : close;
                currentHigh  = (priorDayHLC == HLCCalculationMode.UserDefinedValues) ? userDefinedHigh : Math.Max(currentHigh, high);
                currentLow   = (priorDayHLC == HLCCalculationMode.UserDefinedValues) ? userDefinedLow : Math.Min(currentLow, low);
            }

            if (pivotRangeType == PivotRange.Daily)
            {
                currentDate = lastBarTimeStamp;
            }
            if (pivotRangeType == PivotRange.Weekly)
            {
                currentWeek = lastBarTimeStamp;
            }
            if (pivotRangeType == PivotRange.Monthly)
            {
                currentMonth = lastBarTimeStamp;
            }

            if ((pivotRangeType == PivotRange.Daily && currentDate != Cbi.Globals.MinDate) ||
                (pivotRangeType == PivotRange.Weekly && currentWeek != Cbi.Globals.MinDate) ||
                (pivotRangeType == PivotRange.Monthly && currentMonth != Cbi.Globals.MinDate))
            {
                PP.Set(pp);
                R1.Set(r1);
                S1.Set(s1);
                R2.Set(r2);
                S2.Set(s2);
                R3.Set(r3);
                S3.Set(s3);
                //    PPR1.Set(ppr1);
                //    PPS1.Set(pps1);
                //    R1R2.Set(r1r2);
                //    S1S2.Set(s1s2);
                //    R2R3.Set(r2r3);
                //    S2S3.Set(s2s3);
            }
        }
Beispiel #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:
					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
		}