Exemplo n.º 1
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);
            }
            if (bars.BarsPeriod.Value == 1)
            {
                AddBar(bars, open, high, low, close, time, volume, bid, ask);
            }
            else if (bars.Count == 0)
            {
                AddBar(bars, open, high, low, close, time, volume);
            }
            else if (bars.Count > 0 && (!bars.IsResetOnNewTradingDay || !isNewSession) && bars.BarsPeriod.Value > 1 && bars.TickCount < bars.BarsPeriod.Value)
            {
                UpdateBar(bars, high, low, close, time, volume);
            }
            else
            {
                AddBar(bars, open, high, low, close, time, volume);
            }
        }
Exemplo n.º 2
0
        protected override void OnBarUpdate()
        {
            // Reset for every session
            if (sessionIterator.IsNewSession(Time[0], false))
            {
                sessionIterator.GetNextSession(Time[0], false);
            }

            // Sometimes CurrentDayOHL is not initialized yet for new session.  IDKW
            if (CurrentDayOHL().CurrentHigh[0] == 0 || CurrentDayOHL().CurrentLow[0] == 0)
            {
                return;
            }

            MidPoint[0] = ((CurrentDayOHL().CurrentHigh[0] - CurrentDayOHL().CurrentLow[0]) / 2) + CurrentDayOHL().CurrentLow[0];

            // Set brush to Transparent on first tick of new session
            // to disconnect indicator plot between sesions.  Plots are
            // relative to current bar and last bar.
            if (Bars.IsFirstBarOfSession && IsFirstTickOfBar)
            {
                PlotBrushes[0][0] = Brushes.Transparent;
            }

            // Draw line between start of session and first bar since the
            // plot is set to transparent for the session disconnect effect
            if (Bars.IsFirstBarOfSession)
            {
                RemoveDrawObject(Time[0].Date.ToString() + "mid");
                Draw.Line(this, Time[0].Date.ToString() + "mid", true, sessionIterator.ActualSessionBegin, MidPoint[0], Time[0], MidPoint[0], Plots[0].Brush, Plots[0].DashStyleHelper, (int)Plots[0].Pen.Thickness);
            }
        }
Exemplo n.º 3
0
        private DateTime TimeToBarTime(Bars bars, DateTime time, bool isBar)
        {
            if (SessionIterator.IsNewSession(time, isBar))
            {
                SessionIterator.GetNextSession(time, isBar);
            }

            if (bars.IsResetOnNewTradingDay || !bars.IsResetOnNewTradingDay && bars.Count == 0)
            {
                DateTime barTimeStamp = isBar
                                        ? SessionIterator.ActualSessionBegin.AddSeconds(Math.Ceiling(Math.Ceiling(Math.Max(0, time.Subtract(SessionIterator.ActualSessionBegin).TotalSeconds)) / bars.BarsPeriod.Value) * bars.BarsPeriod.Value)
                                        : SessionIterator.ActualSessionBegin.AddSeconds(bars.BarsPeriod.Value + Math.Floor(Math.Floor(Math.Max(0, time.Subtract(SessionIterator.ActualSessionBegin).TotalSeconds)) / bars.BarsPeriod.Value) * bars.BarsPeriod.Value);
                if (bars.TradingHours.Sessions.Count > 0 && barTimeStamp > SessionIterator.ActualSessionEnd)                 // Cut last bar in session down to session end on odd session end time
                {
                    barTimeStamp = SessionIterator.ActualSessionEnd;
                }
                return(barTimeStamp);
            }
            else
            {
                DateTime lastBarTime  = bars.GetTime(bars.Count - 1);
                DateTime barTimeStamp = isBar
                                        ? lastBarTime.AddSeconds(Math.Ceiling(Math.Ceiling(Math.Max(0, time.Subtract(lastBarTime).TotalSeconds)) / bars.BarsPeriod.Value) * bars.BarsPeriod.Value)
                                        : lastBarTime.AddSeconds(bars.BarsPeriod.Value + Math.Floor(Math.Floor(Math.Max(0, time.Subtract(lastBarTime).TotalSeconds)) / bars.BarsPeriod.Value) * bars.BarsPeriod.Value);
                if (bars.TradingHours.Sessions.Count > 0 && barTimeStamp > SessionIterator.ActualSessionEnd)
                {
                    DateTime saveActualSessionEnd = SessionIterator.ActualSessionEnd;
                    SessionIterator.GetNextSession(SessionIterator.ActualSessionEnd.AddSeconds(1), isBar);
                    barTimeStamp = SessionIterator.ActualSessionBegin.AddSeconds((int)barTimeStamp.Subtract(saveActualSessionEnd).TotalSeconds);
                }
                return(barTimeStamp);
            }
        }
Exemplo n.º 4
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;
                }
            }
        }
Exemplo n.º 5
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)
            {
                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 (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.Value || isBar && bars.Count > 0 && barTime == bars.LastBarTime.Date || !isBar && bars.Count > 0 && barTime <= bars.LastBarTime.Date)
                {
                    UpdateBar(bars, high, low, close, barTime, volume);
                }
                else
                {
                    AddBar(bars, open, high, low, close, barTime, volume);
                }
            }
        }
Exemplo n.º 6
0
        protected override void OnMarketData(MarketDataEventArgs marketDataUpdate)
        {
            // Workaround for market replay backfilling all of replay sessions data(as historical data)
            // Replay should only backfill history up to replay time, so make sure any historical ticks
            // are before the current replay time.
            if ((Connection.PlaybackConnection != null) &&
                (State == State.Historical) &&
                (marketDataUpdate.Time >= Connection.PlaybackConnection.Now))
            {
                if (PrintDebug)
                {
                    Print("Filter Hit - MarketDataEvent Time :" + marketDataUpdate.Time.ToString() +
                          " Playback Time: " + Connection.PlaybackConnection.Now.ToString() +
                          " Event Type: " + marketDataUpdate.MarketDataType +
                          " State: " + State);
                }
                return;
            }

            // Reset for every session
            if (sessionIterator.IsNewSession(marketDataUpdate.Time, false))
            {
                if (PrintDebug)
                {
                    Print("NewSession: " + marketDataUpdate.Time.ToString());
                }
                totalShares  = 0;
                totalDollars = 0;
                sessionIterator.GetNextSession(marketDataUpdate.Time, false);
            }

            // Check session time
            if (!sessionIterator.IsInSession(marketDataUpdate.Time, false, true))
            {
                return;
            }

            // Is this a trade(not bid or ask)
            if (marketDataUpdate.MarketDataType == MarketDataType.Last)
            {
                totalShares  += marketDataUpdate.Volume;
                totalDollars += marketDataUpdate.Volume * marketDataUpdate.Price;
                Vwap[0]       = totalDollars / totalShares;
                if (PrintDebug)
                {
                    Print(marketDataUpdate.Time.ToString() + " Session total shares: " + totalShares.ToString() + " " + State);
                }
            }
        }
        private DateTime TimeToBarTimeSecond(Bars bars, DateTime time, bool isBar)
        {
            if (SessionIterator.IsNewSession(time, isBar))
            {
                SessionIterator.GetNextSession(time, isBar);
            }

            DateTime barTimeStamp = SessionIterator.ActualSessionBegin.AddSeconds(Math.Ceiling(Math.Ceiling(Math.Max(0, time.Subtract(SessionIterator.ActualSessionBegin).TotalSeconds)) / bars.BarsPeriod.BaseBarsPeriodValue) * bars.BarsPeriod.BaseBarsPeriodValue);

            if (bars.TradingHours.Sessions.Count > 0 && barTimeStamp > SessionIterator.ActualSessionEnd)
            {
                barTimeStamp = SessionIterator.ActualSessionEnd <= Core.Globals.MinDate ? barTimeStamp : SessionIterator.ActualSessionEnd;
            }
            return(barTimeStamp);
        }
        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
        }
Exemplo n.º 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);
            }

            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;
        }
Exemplo n.º 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)
        {
            ///Beta 9 addition!
            // build a session iterator from the bars object being updated
            if (SessionIterator == null)
            {
                SessionIterator = new SessionIterator(bars);
            }

            // check if we are in a new trading session based on the trading hours selected by the user
            bool isNewSession = SessionIterator.IsNewSession(time, isBar);

            // calculate the new trading day
            if (isNewSession)
            {
                SessionIterator.CalculateTradingDay(time, isBar);
            }

            ///End Beta 9 addition


            //### First Bar
            if (bars.Count == 0 || (bars.IsResetOnNewTradingDay && isNewSession))
            {
                tickSize       = bars.Instrument.MasterInstrument.TickSize;
                trendOffset    = bars.BarsPeriod.Value * tickSize;
                reversalOffset = bars.BarsPeriod.Value2 * tickSize;
                //bars.BarPeriod.BaseBarsPeriodValue = bars.BarsPeriod.Value;	//### Remove to customize OpenOffset
                openOffset = Math.Ceiling((double)bars.BarsPeriod.BaseBarsPeriodValue * 1) * tickSize;

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

                AddBar(bars, barOpen, barOpen, barOpen, barOpen, time, volume);
            }
            //### Subsequent Bars
            else
            {
                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, (maxExceeded ? thisClose : bars.GetHigh(bars.Count - 1)), (minExceeded ? thisClose : bars.GetLow(bars.Count - 1)), thisClose, time, volume);

                    //### 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);
                }
                //### Current Bar Still Developing
                else
                {
                    UpdateBar(bars, (close > bars.GetHigh(bars.Count - 1) ? close : bars.GetHigh(bars.Count - 1)), (close < bars.GetLow(bars.Count - 1) ? close : bars.GetLow(bars.Count - 1)), close, time, volume);
                }
            }
            bars.LastPrice = close;
        }
Exemplo n.º 11
0
        protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask)
        {
            if (SessionIterator == null)
            {
                SessionIterator = new SessionIterator(bars);
            }

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

            if (isNewSession)
            {
                SessionIterator.GetNextSession(time, isBar);
            }
            if (bars.Count == 0 || bars.IsResetOnNewTradingDay && isNewSession)
            {
                AddBar(bars, open, high, low, close, time, volume);
            }
            else
            {
                double barClose   = bars.GetClose(bars.Count - 1);
                double barHigh    = bars.GetHigh(bars.Count - 1);
                double barLow     = bars.GetLow(bars.Count - 1);
                double tickSize   = bars.Instrument.MasterInstrument.TickSize;
                double rangeValue = Math.Floor(10000000.0 * bars.BarsPeriod.Value * tickSize) / 10000000.0;

                if (close.ApproxCompare(barLow + rangeValue) > 0)
                {
                    double newClose = barLow + rangeValue;                                     // Every bar closes either with high or low
                    if (newClose.ApproxCompare(barClose) > 0)
                    {
                        UpdateBar(bars, newClose, barLow, newClose, time, 0);
                    }

                    // If there's still a gap, fill with phantom bars
                    double newBarOpen = newClose + tickSize;
                    while (close.ApproxCompare(newClose) > 0)
                    {
                        newClose = Math.Min(close, newBarOpen + rangeValue);
                        AddBar(bars, newBarOpen, newClose, newBarOpen, newClose, time, close.ApproxCompare(newClose) > 0 ? 0 : volume);
                        newBarOpen = newClose + tickSize;
                    }
                }
                else if ((barHigh - rangeValue).ApproxCompare(close) > 0)
                {
                    double newClose = barHigh - rangeValue;                                     // Every bar closes either with high or low
                    if (barClose.ApproxCompare(newClose) > 0)
                    {
                        UpdateBar(bars, barHigh, newClose, newClose, time, 0);
                    }

                    // if there's still a gap, fill with phantom bars
                    double newBarOpen = newClose - tickSize;
                    while (newClose.ApproxCompare(close) > 0)
                    {
                        newClose = Math.Max(close, newBarOpen - rangeValue);
                        AddBar(bars, newBarOpen, newBarOpen, newClose, newClose, time, newClose.ApproxCompare(close) > 0 ? 0 : volume);
                        newBarOpen = newClose - tickSize;
                    }
                }
                else
                {
                    UpdateBar(bars, close > barHigh ? close : barHigh, close < barLow ? close : barLow, close, time, volume);
                }
            }
            bars.LastPrice = close;
        }
Exemplo n.º 12
0
        protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask)
        {
            // method variables
            bool   isNewSession = SessionIterator.IsNewSession(time, isBar);
            double tickSize     = bars.Instrument.MasterInstrument.TickSize;

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

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

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

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

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

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

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

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

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

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

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

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

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

                        // update fields
                        maxCompare = bars.Instrument.MasterInstrument.Compare(close, thisMax);
                        minCompare = bars.Instrument.MasterInstrument.Compare(close, thisMin);
                    }while (maxCompare > 0 || minCompare < 0);
                }
                else
                {
                    UpdateBar(bars, (close > barHigh ? close : barHigh), (close < barLow ? close : barLow), close, time, volume);
                }
            }
            bars.LastPrice = close;
        }
Exemplo n.º 13
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;
        }
Exemplo n.º 14
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;
        }
Exemplo n.º 15
0
        protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask)
        {
            if (SessionIterator == null)
            {
                SessionIterator = new SessionIterator(bars);
            }

            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;
        }
Exemplo n.º 16
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
        }
        protected override void OnMarketData(MarketDataEventArgs marketDataUpdate)
        {
            // Workaround for market replay sending out all of replay sessions data(as historical data)
            // Replay should only backfill history up to replay time, so make sure any historical ticks
            // are before the current replay time.
            // this code to OnBar and set for on price change notifications for better performance once
            // this bug is resolved
            if ((Connection.PlaybackConnection != null) &&
                (State == State.Historical) &&
                (marketDataUpdate.Time >= Connection.PlaybackConnection.Now))
            {
                return;
            }

            bool redrawHigh = false;
            bool redrawLow  = false;

            // Reset for every session
            if (sessionIterator.IsNewSession(marketDataUpdate.Time, true))
            {
                orHigh = Double.MinValue;
                orLow  = Double.MaxValue;
                sessionIterator.GetNextSession(marketDataUpdate.Time, true);
                renderEndTime = sessionIterator.ActualSessionEnd;
                orCutoffTime  = sessionIterator.ActualSessionBegin.AddSeconds(CutoffSeconds);
                rendered      = false;
                orComplete    = false;
            }

            if (orComplete)
            {
                return;
            }

            // Check session time
            if (!sessionIterator.IsInSession(marketDataUpdate.Time, false, true))
            {
                return;
            }

            // keep track of high low
            if (marketDataUpdate.MarketDataType == MarketDataType.Last)
            {
                if (!orComplete && (marketDataUpdate.Time <= orCutoffTime))
                {
                    redrawHigh = false;
                    if (marketDataUpdate.Price > orHigh)
                    {
                        orHigh         = marketDataUpdate.Price;
                        orHighDateTime = marketDataUpdate.Time;
                        redrawHigh     = true;
                        Values[0][0]   = orHigh;
                    }

                    redrawLow = false;
                    if (marketDataUpdate.Price < orLow)
                    {
                        orLow         = marketDataUpdate.Price;
                        orLowDateTime = marketDataUpdate.Time;
                        redrawLow     = true;
                        Values[1][0]  = orLow;
                    }

                    if (redrawHigh)
                    {
                        RemoveDrawObject(marketDataUpdate.Time.Date.ToString() + "or_high");
                        Draw.Line(this, marketDataUpdate.Time.Date.ToString() + "or_high", true, orHighDateTime, orHigh, renderEndTime, orHigh, HighBrush, DashStyleHelper.Dot, HighBrushWidth);
                    }

                    if (redrawLow)
                    {
                        RemoveDrawObject(marketDataUpdate.Time.Date.ToString() + "or_low");
                        Draw.Line(this, marketDataUpdate.Time.Date.ToString() + "or_low", true, orLowDateTime, orLow, renderEndTime, orLow, LowBrush, DashStyleHelper.Dot, LowBrushWidth);
                    }
                }

                // On first tick past cutoff time mark opening range calc complete and
                // draw the hi and low lines across the entire sesson.
                if ((marketDataUpdate.Time > orCutoffTime) && !orComplete)
                {
                    orComplete = true;
                    RemoveDrawObject(marketDataUpdate.Time.Date.ToString() + "or_high");
                    Draw.Line(this, marketDataUpdate.Time.Date.ToString() + "or_high", true, orHighDateTime, orHigh, renderEndTime, orHigh, HighBrush, DashStyleHelper.Solid, HighBrushWidth);
                    RemoveDrawObject(marketDataUpdate.Time.Date.ToString() + "or_low");
                    Draw.Line(this, marketDataUpdate.Time.Date.ToString() + "or_low", true, orLowDateTime, orLow, renderEndTime, orLow, LowBrush, DashStyleHelper.Solid, LowBrushWidth);

                    // Go back to first bar and Set all the high and low plot
                    // values for the day so databox works for indicator
                    for (int x = 0; x < Bars.BarsSinceNewTradingDay; x++)
                    {
                        Values[0][x] = orHigh;
                        Values[1][x] = orLow;
                    }
                }
            }
        }