示例#1
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);
            }
        }
示例#2
0
        protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask)
        {
            if (SessionIterator == null)
            {
                SessionIterator = new SessionIterator(bars);
            }

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

            if (isNewSession)
            {
                SessionIterator.GetNextSession(time, isBar);
            }
            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);
            }
        }
示例#3
0
        private DateTime GetLastBarSessionDate(DateTime time, PivotRange pivotRange)
        {
            // Check the time[0] against the previous session end
            if (time > cacheSessionEnd)
            {
                if (Bars.BarsType.IsIntraday)
                {
                    // Make use of the stored session iterator to find the next session...
                    storedSession.GetNextSession(time, true);
                    // Store the actual session's end datetime as the session
                    cacheSessionEnd = storedSession.ActualSessionEnd;
                    // We need to convert that time from the session to the users time zone settings
                    sessionDateTmp = TimeZoneInfo.ConvertTime(cacheSessionEnd.AddSeconds(-1), Globals.GeneralOptions.TimeZoneInfo, Bars.TradingHours.TimeZoneInfo).Date;
                }
                else
                {
                    sessionDateTmp = time.Date;
                }
            }

            if (pivotRange == PivotRange.Daily)
            {
                if (sessionDateTmp != cacheSessionDate)
                {
                    if (newSessionBarIdxArr.Count == 0 || newSessionBarIdxArr.Count > 0 && CurrentBar > newSessionBarIdxArr[newSessionBarIdxArr.Count - 1])
                    {
                        newSessionBarIdxArr.Add(CurrentBar);
                    }
                    cacheSessionDate = sessionDateTmp;
                }
                return(sessionDateTmp);
            }

            DateTime tmpWeeklyEndDate = RoundUpTimeToPeriodTime(sessionDateTmp, PivotRange.Weekly);

            if (pivotRange == PivotRange.Weekly)
            {
                if (tmpWeeklyEndDate != cacheWeeklyEndDate)
                {
                    if (newSessionBarIdxArr.Count == 0 || newSessionBarIdxArr.Count > 0 && CurrentBar > newSessionBarIdxArr[newSessionBarIdxArr.Count - 1])
                    {
                        newSessionBarIdxArr.Add(CurrentBar);
                    }
                    cacheWeeklyEndDate = tmpWeeklyEndDate;
                }
                return(tmpWeeklyEndDate);
            }

            DateTime tmpMonthlyEndDate = RoundUpTimeToPeriodTime(sessionDateTmp, PivotRange.Monthly);

            if (tmpMonthlyEndDate != cacheMonthlyEndDate)
            {
                if (newSessionBarIdxArr.Count == 0 || newSessionBarIdxArr.Count > 0 && CurrentBar > newSessionBarIdxArr[newSessionBarIdxArr.Count - 1])
                {
                    newSessionBarIdxArr.Add(CurrentBar);
                }
                cacheMonthlyEndDate = tmpMonthlyEndDate;
            }
            return(tmpMonthlyEndDate);
        }
        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);
            }
        }
示例#5
0
 public void RecalculateSession(DateTime time)
 {
     if (sessionIterator == null)
     {
         if (BarsArray != null)
         {
             sessionIterator = new SessionIterator(BarsArray[1]);
         }
     }
     sessionIterator.GetNextSession(time, false);
 }
示例#6
0
        protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask)
        {
            if (SessionIterator == null)
            {
                SessionIterator = new SessionIterator(bars);
            }

            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;
                }
            }
        }
示例#7
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);
        }
示例#9
0
        private DateTime GetLastBarSessionDate(DateTime time)
        {
            if (time <= cacheSessionEnd)
            {
                return(sessionDateTmp);
            }
            if (!Bars.BarsType.IsIntraday)
            {
                return(sessionDateTmp);
            }

            storedSession.GetNextSession(time, true);
            cacheSessionEnd = storedSession.ActualSessionEnd;
            sessionDateTmp  = TimeZoneInfo.ConvertTime(cacheSessionEnd.AddSeconds(-1), Globals.GeneralOptions.TimeZoneInfo, Bars.TradingHours.TimeZoneInfo).Date;

            if (newSessionBarIdx.Count == 0 || newSessionBarIdx.Count > 0 && CurrentBar > newSessionBarIdx[newSessionBarIdx.Count - 1])
            {
                newSessionBarIdx.Add(CurrentBar);
            }

            return(sessionDateTmp);
        }
示例#10
0
        protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask)
        {
            if (SessionIterator == null)
            {
                SessionIterator = new SessionIterator(bars);
            }

            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;
        }
示例#11
0
        protected override void OnBarUpdate()
        {
            if (CurrentBars[0] < BarsRequiredToTrade || CurrentBars[1] < BarsRequiredToTrade)
            {
                return;
            }

            if (BarsInProgress == 0)
            {
                sessionIterator.GetNextSession(Time[0], true);
            }

            // if after the exit on close, prevent new orders until the new session
            if (Times[1][0] >= sessionIterator.ActualSessionEnd.AddSeconds(-ExitOnSessionCloseSeconds) && Times[1][0] <= sessionIterator.ActualSessionEnd)
            {
                exitOnCloseWait = true;
            }

            // an exit on close occurred in the previous session, reset for a new entry on the first bar of a new session
            if (exitOnCloseWait && Bars.IsFirstBarOfSession)
            {
                entryOrder      = null;
                profitTarget    = null;
                stopLoss        = null;
                exitFlat        = null;
                exitSession     = null;
                exitOnCloseWait = false;
            }

            // the entry logic can be done when the primary series is processing
            if (BarsInProgress == 0)
            {
                // Reset the trade profitability counter every day and get the number of trades taken in total.
                if (Bars.IsFirstBarOfSession && IsFirstTickOfBar)
                {
                    InitializeTradeAccounting();
                }

                // because this is a demonstration, this code will cause any historical position
                // to be exited on the last historical bar so the strategy will always start flat in real-time
                if (State == State.Historical && CurrentBar == BarsArray[0].Count - 2)
                {
                    if (entryOrder != null)
                    {
                        ExitToStartFlat();
                    }
                }
                // if this is not the last historical bar, and entryOrder is null, then place an entry order
                //else if (!exitOnCloseWait && entryOrder == null && profitTarget == null && stopLoss == null)
                else if (!exitOnCloseWait)
                {
                    suppressOco = false;
                    entryOrder  = placeHolderOrder;
                    ReversalTrade();
                    AfterLunchBollingerTrade();
                    PullbackTrade();
                }
            }

            // all code below this point takes places during BarsInProgress 1 when the tick series is processing
            if (BarsInProgress != 1)
            {
                return;
            }

            if (ordersCancelled)
            {
                message = string.Format("{0} | OBU | stop and/or target cancelled or rejected", Times[1][0]);

                // if the orders were cancelled due to the exit on close, do not submit an order to flatten
                if (!exitOnCloseWait && entryOrder != null && entryOrder.OrderState == OrderState.Filled)
                {
                    ExitForCancel();
                }

                if (entryOrder == null || entryOrder.OrderState != OrderState.Filled)
                {
                    Print(string.Format("{0} | OBU | entry not filled or is null", Times[1][0]));
                }

                ordersCancelled = false;
                return;
            }

            // trailing logic
            // the profitTarget/stopLoss is first created when the entry order fills. If it exists then move it.

            // trigger the chase action when the current price is further than the set distance to the profit target
            if (ChaseProfitTarget &&
                profitTarget != null && (profitTarget.OrderState == OrderState.Accepted || profitTarget.OrderState == OrderState.Working) &&
                Close[0] < currentPtPrice - ProfitTargetDistance * tickSizeSecondary)
            {
                // setting chase profit target
                if (isLongTrade)
                {
                    currentPtPrice = Close[0] + ProfitTargetDistance * tickSizeSecondary;
                    ExitLongLimit(1, true, entryOrder.Quantity, currentPtPrice, "profit target", entryOrder.Name);
                }
                else
                {
                    currentPtPrice = Close[0] - ProfitTargetDistance * tickSizeSecondary;
                    ExitLongLimit(1, true, entryOrder.Quantity, currentPtPrice, "profit target", entryOrder.Name);
                }
            }

            // trigger the trail action when the current price is further than the set distance to the stop loss
            if (TrailStopLoss &&
                stopLoss != null && (stopLoss.OrderState == OrderState.Accepted || stopLoss.OrderState == OrderState.Working) &&
                Close[0] > currentSlPrice + StopLossDistance * tickSizeSecondary)
            {
                // setting trailing stop loss
                if (isLongTrade)
                {
                    currentSlPrice = Close[0] - StopLossDistance * tickSizeSecondary;
                    ExitLongStopMarket(1, true, entryOrder.Quantity, currentSlPrice, "stop loss", entryOrder.Name);
                }
                else
                {
                    currentSlPrice = Close[0] + StopLossDistance * tickSizeSecondary;
                    ExitLongStopMarket(1, true, entryOrder.Quantity, currentSlPrice, "stop loss", entryOrder.Name);
                }
            }
        }
示例#12
0
        protected override void OnBarUpdate()
        {
            if (CurrentBars[0] < BarsRequiredToTrade || CurrentBars[1] < BarsRequiredToTrade)
            {
                return;
            }

            if (BarsInProgress == 0)
            {
                if (CurrentBar == 0 || Bars.IsFirstBarOfSession)
                {
                    sessionIterator.GetNextSession(Time[0], true);
                }

                // if after the exit on close time, prevent new orders until the new session
                if (Times[1][0] >= sessionIterator.ActualSessionEnd.AddSeconds(-ExitOnSessionCloseSeconds) && Times[1][0] <= sessionIterator.ActualSessionEnd)
                {
                    exitOnCloseWait = true;
                }

                // reset for a new entry on the first bar of a new session
                else if (exitOnCloseWait && Bars.IsFirstBarOfSession)
                {
                    exitOnCloseWait = false;
                }

                if (State == State.Historical && CurrentBar == BarsArray[0].Count - 2 && Position.MarketPosition == MarketPosition.Long)
                {
                    ExitLong(1, 1, "exit to start flat", string.Empty);
                }

                else if (!exitOnCloseWait && Position.MarketPosition == MarketPosition.Flat)
                {
                    // Reset the stop loss to the original distance when all positions are closed before placing a new entry

                    currentPtPrice = Close[0] + ProfitTargetDistance * TickSize;
                    currentSlPrice = Close[0] - StopLossDistance * TickSize;

                    if (UseProfitTarget)
                    {
                        SetProfitTarget(CalculationMode.Price, currentPtPrice);
                    }

                    if (UseStopLoss)
                    {
                        SetStopLoss(CalculationMode.Price, currentSlPrice);
                    }

                    Print(string.Format("ProfitChaseStopTrailSetMethodsExample:: tradeCount {0}", tradeCount++));

                    EnterLong(1, 1, string.Empty);
                }
            }

            if (BarsInProgress == 1 && Position.MarketPosition == MarketPosition.Long)
            {
                if (UseProfitTarget && ChaseProfitTarget && Close[0] < currentPtPrice - ProfitTargetDistance * TickSize)
                {
                    currentPtPrice = Close[0] + ProfitTargetDistance * TickSize;
                    SetProfitTarget(CalculationMode.Price, currentPtPrice);
                }

                if (UseStopLoss && TrailStopLoss && Close[0] > currentSlPrice + StopLossDistance * TickSize)
                {
                    currentSlPrice = Close[0] - StopLossDistance * TickSize;
                    SetStopLoss(CalculationMode.Price, currentSlPrice);
                }
            }
        }
示例#13
0
        protected override void OnBarUpdate()
        {
            //Print(Times[BarsInProgress][0]+" "+BarsInProgress);
            if (isStartOfNewSessionRTH())
            {
                //Print("RTH "+Times[RTH][0]);

                //Print(Times[BarsInProgress][0]+" "+BarsInProgress);
                //Print(Times[ETH][0]+" session: "+ethSessionIterator.ActualSessionBegin+"  "+CurrentBars[ETH]);

                rthSessionIterator.GetNextSession(Times[RTH][0], false);

                if (tpoProfile != null)
                {
                    update(tpoProfile);
                    tpoProfiles.Add(tpoProfile);
                }
                tpoProfile = new JBTPOProfile(RTH, rthSessionIterator.ActualSessionBegin);
            }
            else if (isStartOfNewSessionETH())
            {
                //Print("ETH "+Times[ETH][0]);

                //Print(Times[BarsInProgress][0]+" "+BarsInProgress);
                //Print(Times[ETH][0]+" session: "+ethSessionIterator.ActualSessionBegin+"  "+CurrentBars[ETH]);

                ethSessionIterator.GetNextSession(Times[ETH][0], false);

                if (tpoProfile != null)
                {
                    update(tpoProfile);
                    tpoProfiles.Add(tpoProfile);
                }

                tpoProfile = new JBTPOProfile(ETH, ethSessionIterator.ActualSessionBegin);
            }

            if (BarsInProgress == RTH && CurrentBars[RTH] != activeBarRTH)
            {
                if (tpoProfile != null)
                {
                    if (State == State.Realtime)
                    {
                        update(tpoProfile);
                    }
                    tpoId = (Times[RTH][0] - tpoProfile.sessionStart).TotalSeconds;
                }
                activeBarRTH = CurrentBars[RTH];
                //Print("RTH TPO ID "+Times[RTH][0]+" "+rthTPOId);
            }
            else if (BarsInProgress == ETH && CurrentBars[ETH] != activeBarETH)
            {
                if (tpoProfile != null)
                {
                    if (State == State.Realtime)
                    {
                        update(tpoProfile);
                    }
                    tpoId = (Times[ETH][0] - tpoProfile.sessionStart).TotalSeconds;
                }
                activeBarETH = CurrentBars[ETH];
                //Print("ETH TPO ID "+Times[ETH][0]+" "+rthTPOId);
            }


            if (tpoProfile != null)
            {
                tpoProfile.add(Closes[BarsInProgress][0], tpoId);
            }
        }
示例#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;
        }
示例#15
0
        protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask)
        {
            if (SessionIterator == null)
            {
                SessionIterator = new SessionIterator(bars);
            }

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

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

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

                break;
            }

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

                break;
            }

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

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

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

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

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

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

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

                break;
            }

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

                break;
            }

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

                break;
            }
            }

            bars.LastPrice = haClose;
        }
        protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask)
        {
            if (SessionIterator == null)
            {
                SessionIterator = new SessionIterator(bars);
            }
            bool isNewSession = SessionIterator.IsNewSession(time, isBar);

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

            #region Building Bars from Base Period

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

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

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

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

                break;

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

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

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

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

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

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

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

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

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

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

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

            if (bars.Count == 0 || IsIntraday && bars.IsResetOnNewTradingDay && isNewSession)
            {
                if (bars.Count > 0)
                {
                    double   lastHigh  = bars.GetHigh(bars.Count - 1);
                    double   lastLow   = bars.GetLow(bars.Count - 1);
                    double   lastClose = bars.GetClose(bars.Count - 1);
                    DateTime lastTime  = bars.GetTime(bars.Count - 1);
                    bars.LastPrice = anchorPrice = lastClose;

                    if (bars.Count == tmpCount)
                    {
                        CalculatePfBar(bars, lastHigh, lastLow, lastClose, prevTime == Core.Globals.MinDate ? time : prevTime, lastTime);
                    }
                }

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

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

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

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

            bars.LastPrice = close;
            tmpCount       = bars.Count;
            #endregion
        }
示例#17
0
        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;
        }
示例#18
0
        protected override void OnBarUpdate()
        {
            if (CurrentBars[0] < BarsRequiredToTrade || CurrentBars[1] < BarsRequiredToTrade)
            {
                return;
            }

            if (BarsInProgress == 0)
            {
                sessionIterator.GetNextSession(Time[0], true);
            }

            // if after the exit on close, prevent new orders until the new session
            if (Times[1][0] >= sessionIterator.ActualSessionEnd.AddSeconds(-ExitOnSessionCloseSeconds) && Times[1][0] <= sessionIterator.ActualSessionEnd)
            {
                exitOnCloseWait = true;
            }

            // an exit on close occurred in the previous session, reset for a new entry on the first bar of a new session
            if (exitOnCloseWait && Bars.IsFirstBarOfSession)
            {
                entryOrder         = null;
                profitTarget       = null;
                stopLoss           = null;
                exitFlat           = null;
                exitSession        = null;
                exitOnCloseWait    = false;
                suppressCancelExit = false;
            }

            // the entry logic can be done when the primary series is processing
            if (BarsInProgress == 0)
            {
                // because this is a demonstration, this code will cause any historical position
                // to be exited on the last historical bar so the strategy will always start flat in real-time
                if (State == State.Historical && CurrentBar == BarsArray[0].Count - 2)
                {
                    if (entryOrder != null)
                    {
                        if (profitTarget != null && (profitTarget.OrderState == OrderState.Accepted || profitTarget.OrderState == OrderState.Working))
                        {
                            CancelOrder(profitTarget);
                        }

                        else if (stopLoss != null && (stopLoss.OrderState == OrderState.Accepted || stopLoss.OrderState == OrderState.Working))
                        {
                            CancelOrder(stopLoss);
                        }

                        ordersCancelled    = false;
                        suppressCancelExit = true;

                        exitName = "exit to start flat";
                        exitFlat = placeHolderOrder;
                        SubmitOrderUnmanaged(1, OrderAction.Sell, OrderType.Market, 1, 0, 0, string.Empty, exitName);
                    }
                }
                // if this is not the last historical bar, and entryOrder is null, then place an entry order
                else if (!exitOnCloseWait && entryOrder == null && profitTarget == null && stopLoss == null)
                {
                    Print(string.Format("ProfitChaseStopTrailUnmanagedExample:: tradeCount {0}", tradeCount++));

                    entryName  = "entry";
                    entryOrder = placeHolderOrder;
                    SubmitOrderUnmanaged(1, OrderAction.Buy, OrderType.Market, 1, 0, 0, string.Empty, entryName);
                }
            }

            // all code below this point takes places during BarsInProgress 1 when the secondary series is processing
            if (BarsInProgress != 1)
            {
                return;
            }

            if (ordersCancelled)
            {
                message = string.Format("{0} stop and/or target cancelled or rejected", Times[1][0]);

                if (entryOrder == null || entryOrder.OrderState != OrderState.Filled && PrintDetails)
                {
                    Print(string.Format("{0} | OBU | entry not filled or is null", Times[1][0]));
                }

                // if the orders were cancelled due to the exit on close, do not submit an order to flatten
                if (!exitOnCloseWait && !suppressCancelExit && entryOrder != null && entryOrder.OrderState == OrderState.Filled)
                {
                    message += "; exiting and resetting";
                    if (PrintDetails)
                    {
                        Print(message);
                    }

                    exitName = "exit for cancel";
                    exitFlat = placeHolderOrder;
                    SubmitOrderUnmanaged(1, OrderAction.Sell, OrderType.Market, entryOrder.Filled, 0, 0, string.Empty, exitName);
                }

                ordersCancelled = false;
                return;
            }

            // the profitTarget/stopLoss is first created when the entry order fills. If it exists then move it.

            // trigger the chase action when the current price is further than the set distance to the profit target
            if (ChaseProfitTarget &&
                profitTarget != null && (profitTarget.OrderState == OrderState.Accepted || profitTarget.OrderState == OrderState.Working) &&
                Close[0] < currentPtPrice - ProfitTargetDistance * tickSizeSecondary)
            {
                currentPtPrice = Close[0] + ProfitTargetDistance * tickSizeSecondary;
                ChangeOrder(profitTarget, entryOrder.Filled, currentPtPrice, 0);
            }

            // trigger the trail action when the current price is further than the set distance to the stop loss
            if (TrailStopLoss &&
                stopLoss != null && (stopLoss.OrderState == OrderState.Accepted || stopLoss.OrderState == OrderState.Working) &&
                Close[0] > currentSlPrice + StopLossDistance * tickSizeSecondary)
            {
                currentSlPrice = Close[0] - ProfitTargetDistance * tickSizeSecondary;
                ChangeOrder(stopLoss, entryOrder.Filled, 0, currentSlPrice);
            }
        }
示例#19
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;
        }
示例#20
0
        protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask)
        {
            if (SessionIterator == null)
            {
                SessionIterator = new SessionIterator(bars);
            }

            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;
        }
示例#21
0
        protected override void OnMarketData(MarketDataEventArgs e)
        {
            if (!initDone)
            {
                return;
            }
            if (e.MarketDataType == MarketDataType.Settlement && BarsInProgress == 0)
            {
                settlement = e.Price;
                if (CurrentBars[0] > 1)
                {
                    DrawSettlementRay("SETTLEM " + e.Time.ToString("MMM dd"), Times[0][1], settlement, Times[0][0], SettlementColor);
                }
                return;
            }

            if (e.MarketDataType == MarketDataType.Last)
            {
                if (isStartOfNewSessionRTH())
                {
                    // Print(e.Time+" "+BarsInProgress+" "+BarsArray[RTH].IsFirstBarOfSession);
                    if (tpoProfile != null)
                    {
                        update(tpoProfile);
                        tpoProfiles.Add(tpoProfile);
                    }
                    rthSessionIterator.GetNextSession(e.Time, false);
                    tpoProfile = new JBTPOProfile(RTH, rthSessionIterator.ActualSessionBegin, rthSessionIterator.ActualSessionEnd);
                    // Print("SESSION - "+tpoProfile.sessionStart+" - "+tpoProfile.sessionEnd);
                }
                if (isStartOfNewSessionETH())
                {
                    //Print(e.Time+" "+BarsInProgress+" "+BarsArray[ETH].IsFirstBarOfSession);
                    if (tpoProfile != null)
                    {
                        update(tpoProfile);
                        tpoProfiles.Add(tpoProfile);
                    }
                    ethSessionIterator.GetNextSession(e.Time, false);
                    tpoProfile = new JBTPOProfile(ETH, ethSessionIterator.ActualSessionBegin, ethSessionIterator.ActualSessionEnd);
                    // Print("SESSION - "+tpoProfile.sessionStart+" - "+tpoProfile.sessionEnd);
                }

                if (BarsInProgress == RTH && CurrentBars[RTH] != activeBarRTH)
                {
                    tpoId        = (Times[RTH][0] - tpoProfile.sessionStart).TotalSeconds;
                    activeBarRTH = CurrentBars[RTH];
                }
                else if (BarsInProgress == ETH && CurrentBars[ETH] != activeBarETH)
                {
                    tpoId        = (Times[ETH][0] - tpoProfile.sessionStart).TotalSeconds;
                    activeBarETH = CurrentBars[ETH];
                }
                if ((BarsInProgress == RTH || BarsInProgress == ETH) && tpoProfile != null)
                {
                    //Print(e.Time+" "+e.Price);
                    if (e.Time >= tpoProfile.sessionStart && e.Time < tpoProfile.sessionEnd)
                    {
                        tpoProfile.add(e.Price, tpoId);
                    }
                }
                else if (BarsInProgress == 0 && CurrentBars[0] != activeBar)
                {
                    if (tpoProfile != null)
                    {
                        update(tpoProfile);
                    }
                    activeBar = CurrentBars[0];
                }
            }
        }
示例#22
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;
                    }
                }
            }
        }