/// <summary> /// Hold the indicator volume from the underlining indicator /// /// </summary> #region Methods public double GetPriceByType(int barNo, PriceSubtype priceType) { Print(CurrentBar + ":GetPriceByType=" + barNo + "," + priceType); double prc = 0; switch (priceType) { case PriceSubtype.Low: prc = Bars.GetLow(barNo); break; case PriceSubtype.High: prc = Bars.GetHigh(barNo); break; case PriceSubtype.Open: prc = Bars.GetOpen(barNo); break; case PriceSubtype.Close: prc = Bars.GetClose(barNo); break; } return(prc); }
public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars) { Bars bars = chartBars.Bars; if (chartBars.FromIndex > 0) { chartBars.FromIndex--; } SharpDX.Direct2D1.PathGeometry lineGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory); GeometrySink sink = lineGeometry.Open(); sink.BeginFigure(new Vector2(chartControl.GetXByBarIndex(chartBars, chartBars.FromIndex > -1 ? chartBars.FromIndex : 0), chartScale.GetYByValue(bars.GetClose(chartBars.FromIndex > -1 ? chartBars.FromIndex : 0))), FigureBegin.Filled); for (int idx = chartBars.FromIndex + 1; idx <= chartBars.ToIndex; idx++) { double closeValue = bars.GetClose(idx); float close = chartScale.GetYByValue(closeValue); float x = chartControl.GetXByBarIndex(chartBars, idx); sink.AddLine(new Vector2(x, close)); } sink.EndFigure(FigureEnd.Open); sink.Close(); AntialiasMode oldAliasMode = RenderTarget.AntialiasMode; RenderTarget.AntialiasMode = AntialiasMode.PerPrimitive; RenderTarget.DrawGeometry(lineGeometry, UpBrushDX, (float)Math.Max(1, chartBars.Properties.ChartStyle.BarWidth)); RenderTarget.AntialiasMode = oldAliasMode; lineGeometry.Dispose(); }
private void HandleProfitChasing() { if (PosFlat()) { // this is not possible Debug.Assert(!PosFlat(), "ASSERT: Position is flat while HandleProfitChasing"); return; } // if market trend go against profit positions, then flatten position and take profits if (PosLong()) { if (Bars.GetClose(CurrentBar) < Bars.GetClose(CurrentBar - 1)) { //Print(Bars.GetTime(CurrentBar).ToString("yyyy-MM-ddTHH:mm:ss.ffffffK") + " HandleProfitChasing::" + " currPos=" + currPos.ToString() + " closedPrice=" + closedPrice.ToString() + " Close[0]=" + Close[0].ToString() + " closedPrice + profitChasing=" + (closedPrice + profitChasing * TickSize).ToString() + " >>>>>> W I N N E R >>>>>> Profits= " + (Close[0] - closedPrice).ToString()); Print(Bars.GetTime(CurrentBar).ToString("yyyy-MM-ddTHH:mm:ss.ffffffK") + " HandleProfitChasing::" + " currPos=" + currPos.ToString() + " OPEN=" + closedPrice.ToString() + " CLOSE=" + Close[0].ToString() + " >>>>>> W I N N E R >>>>>> Profits= " + (Close[0] - closedPrice).ToString()); AiFlat(); } } if (PosShort()) { if (Bars.GetClose(CurrentBar) > Bars.GetClose(CurrentBar - 1)) { Print(Bars.GetTime(CurrentBar).ToString("yyyy-MM-ddTHH:mm:ss.ffffffK") + " HandleProfitChasing::" + " currPos=" + currPos.ToString() + " OPEN=" + closedPrice.ToString() + " CLOSE=" + Close[0].ToString() + " >>>>>> W I N N E R >>>>>> Profits= " + (closedPrice - Close[0]).ToString()); AiFlat(); } } }
private bool TouchedProfitChasing() { profitChasingFlag = false; if (PosLong()) { //if (Close[0] >= (closedPrice + profitChasing * TickSize)) if (Bars.GetClose(CurrentBar) >= (closedPrice + profitChasing * TickSize)) { Print(Bars.GetTime(CurrentBar).ToString("yyyy-MM-ddTHH:mm:ss.ffffffK") + " TouchedProfitChasing"); profitChasingFlag = true; return(profitChasingFlag); } } if (PosShort()) { //if (Close[0] <= (closedPrice - profitChasing * TickSize)) if (Bars.GetClose(CurrentBar) <= (closedPrice - profitChasing * TickSize)) { Print(Bars.GetTime(CurrentBar).ToString("yyyy-MM-ddTHH:mm:ss.ffffffK") + " TouchedProfitChasing"); profitChasingFlag = true; return(profitChasingFlag); } } return(profitChasingFlag); }
public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars) { Bars bars = chartBars.Bars; float lineWidth = (float)Math.Max(1, BarWidth); Vector2 point0 = new Vector2(); Vector2 point1 = new Vector2(); Vector2 point2 = new Vector2(); Vector2 point3 = new Vector2(); Vector2 point4 = new Vector2(); Vector2 point5 = new Vector2(); for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++) { SharpDX.Direct2D1.Brush overriddenBrush = chartControl.GetBarOverrideBrush(chartBars, idx); double closeValue = bars.GetClose(idx); float close = chartScale.GetYByValue(closeValue); float high = chartScale.GetYByValue(bars.GetHigh(idx)); float low = chartScale.GetYByValue(bars.GetLow(idx)); double openValue = bars.GetOpen(idx); float open = chartScale.GetYByValue(openValue); float x = chartControl.GetXByBarIndex(chartBars, idx); point0.X = point1.X = x; point0.Y = high - lineWidth * 0.5f; point1.Y = low + lineWidth * 0.5f; SharpDX.Direct2D1.Brush b = overriddenBrush ?? (closeValue >= openValue ? UpBrushDX : DownBrushDX); if (!(b is SharpDX.Direct2D1.SolidColorBrush)) { TransformBrush(b, new RectangleF(point0.X - lineWidth * 1.5f, point0.Y, lineWidth * 3, point1.Y - point0.Y)); } RenderTarget.DrawLine(point0, point1, b, lineWidth); if (!Equals(Mode, OhlcMode.HiLo)) { point2.X = x + lineWidth * 1.5f; point2.Y = close; point3.X = x; point3.Y = close; RenderTarget.DrawLine(point2, point3, b, lineWidth); if (Equals(Mode, OhlcMode.OHLC)) { point4.X = x - lineWidth * 1.5f; point4.Y = open; point5.X = x; point5.Y = open; RenderTarget.DrawLine(point4, point5, b, lineWidth); } } } }
private bool ViolateSoftDeck() { if (PosLong()) { return(Bars.GetClose(CurrentBar) <= (closedPrice - softDeck * TickSize)); } if (PosShort()) { return(Bars.GetClose(CurrentBar) >= (closedPrice + softDeck * TickSize)); } return(false); }
protected override void OnBarUpdate() { // smaFast = SMA(5); // smaSlow = SMA(20); if (CurrentBar > 1) { if (Bars.GetHigh(CurrentBar) - Bars.GetHigh(CurrentBar - 1) < 0 && direction > 0) { max.Add(Bars.GetHigh(CurrentBar - 1)); maxIndex.Add(CurrentBar - 1); upperLines.Clear(); if (min.Count > 15) { min.RemoveAt(0); } if (max.Count > 15) { max.RemoveAt(0); upperTrend(); } } if (Bars.GetLow(CurrentBar) - Bars.GetLow(CurrentBar - 1) > 0 && direction < 0) { min.Add(Bars.GetLow(CurrentBar - 1)); minIndex.Add(CurrentBar - 1); } direction = Bars.GetHigh(CurrentBar) - Bars.GetHigh(CurrentBar - 1); if (max.Count > 15) { max.RemoveAt(0); maxIndex.RemoveAt(0); } PrintTo = PrintTo.OutputTab1; Print(Bars.GetTime(CurrentBar - 1) + ": " + trendState()); if (upperLines.Count > 0) { PrintTo = PrintTo.OutputTab2; Print(Bars.GetTime(CurrentBar) + ": " + upperLines[upperLines.Count - 1].slope + " " + upperLines[upperLines.Count - 1].intercept + " " + upperLines.Count + " " + upperLines[upperLines.Count - 1].tipCount); upperTest = upperLines[upperLines.Count - 1].slope * (CurrentBar - upperLines[upperLines.Count - 1].index) + upperLines[upperLines.Count - 1].intercept; // bottomTest = bottomSlope*(CurrentBar - bottomIndex) + bottomIntercept; if (Bars.GetClose(CurrentBar) > upperTest) { // stopLoss = Math.Round((upperTest - bottomTest)/0.25); //targetProfit = stopLoss*2; SetProfitTarget(CalculationMode.Ticks, 4); SetStopLoss(CalculationMode.Ticks, 4); EnterLong(3); upperLines.RemoveAt(upperLines.Count - 1); } } } }
private bool ViolateSoftDeck() { if (PosLong()) { //return (Bars.GetClose(CurrentBar) <= (closedPrice - softDeck * TickSize)); // For Long position, check violation on tick by tick basis return(Close[0] <= (closedPrice - softDeck * TickSize)); } if (PosShort()) { // For short position, check violation on bar by bar basis return(Bars.GetClose(CurrentBar) >= (closedPrice + softDeck * TickSize)); } return(false); }
public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars) { Bars bars = chartBars.Bars; float barWidth = GetBarPaintWidth(BarWidthUI); RectangleF rect = new RectangleF(); for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++) { Brush overriddenBrush = chartControl.GetBarOverrideBrush(chartBars, idx); Brush overriddenOutlineBrush = chartControl.GetCandleOutlineOverrideBrush(chartBars, idx); double closeValue = bars.GetClose(idx); float close = chartScale.GetYByValue(closeValue); double openValue = bars.GetOpen(idx); float open = chartScale.GetYByValue(openValue); float x = chartControl.GetXByBarIndex(chartBars, idx); Gui.Stroke outlineStroke = closeValue >= openValue ? Stroke : Stroke2; rect.X = x - barWidth * 0.5f + 0.5f; rect.Y = Math.Min(open, close); rect.Width = barWidth - 1; rect.Height = Math.Max(open, close) - Math.Min(open, close); Brush b = overriddenBrush ?? (closeValue >= openValue ? UpBrushDX : DownBrushDX); if (!(b is SolidColorBrush)) { TransformBrush(b, rect); } RenderTarget.FillRectangle(rect, b); b = overriddenBrush ?? outlineStroke.BrushDX; if (!(b is SolidColorBrush)) { TransformBrush(b, rect); } RenderTarget.DrawRectangle(rect, overriddenOutlineBrush ?? outlineStroke.BrushDX, outlineStroke.Width, outlineStroke.StrokeStyle); } }
protected override void 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 }
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 (bars.Count == 0) { AddBar(bars, open, high, low, close, TimeToBarTime(time, bars.BarsPeriod.Value), 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) { UpdateBar(bars, high, low, close, bars.LastBarTime, volume); } } else { AddBar(bars, open, high, low, close, TimeToBarTime(time, bars.BarsPeriod.Value), volume); } }
/// <summary> /// Called when the indicator is plotted. /// </summary> public override void Plot(Graphics graphics, Rectangle bounds, double min, double max) { int lastBar = Math.Min(this.LastBarIndexPainted, Bars.Count - 1); int barsPainted = ChartControl.BarsPainted; int firstBar = this.FirstBarIndexPainted; // Find highest and lowest price points double highPrice = 0; double lowPrice = double.MaxValue; for (int idx = firstBar; idx <= lastBar && idx >= 0; idx++) { highPrice = Math.Max(highPrice, Bars.GetHigh(idx)); lowPrice = Math.Min(lowPrice, Bars.GetLow(idx)); } int volumeBarCount = this.BarCount; double priceRange = highPrice - lowPrice; double priceBoxSize = priceRange / volumeBarCount; double volumeMax = 0; // Pass 1: Fill all VolumeInfo structures with appropriate data for (int i = 0; i < volumeBarCount; i++) { double priceUpper = lowPrice + priceBoxSize * (i + 1); double priceLower = lowPrice + priceBoxSize * i; double priceVolumeUp = 0; double priceVolumeDown = 0; for (int idx = firstBar; idx <= lastBar; idx++) { double checkPrice; switch (PriceType) { case PriceType.Open: checkPrice = Bars.GetOpen(idx); break; case PriceType.Close: checkPrice = Bars.GetClose(idx); break; case PriceType.High: checkPrice = Bars.GetHigh(idx); break; case PriceType.Low: checkPrice = Bars.GetLow(idx); break; case PriceType.Median: checkPrice = (Bars.GetHigh(idx) + Bars.GetLow(idx)) / 2; break; case PriceType.Typical: checkPrice = (Bars.GetHigh(idx) + Bars.GetLow(idx) + Bars.GetClose(idx)) / 3; break; case PriceType.Weighted: checkPrice = (Bars.GetHigh(idx) + Bars.GetLow(idx) + 2 * Bars.GetClose(idx)) / 4; break; default: checkPrice = Bars.GetClose(idx); break; } if (checkPrice >= priceLower && checkPrice < priceUpper) { if (Bars.GetOpen(idx) < Bars.GetClose(idx)) { priceVolumeUp += Bars.GetVolume(idx); } else { priceVolumeDown += Bars.GetVolume(idx); } } } volumeInfo[i].up = priceVolumeUp; volumeInfo[i].down = priceVolumeDown; volumeInfo[i].total = (double)priceVolumeUp + (double)priceVolumeDown; volumeMax = Math.Max(volumeMax, volumeInfo[i].total); } // Pass 2: Paint the volume bars for (int i = 0; i < Math.Min(volumeBarCount, lastBar - firstBar + 1); i++) { double priceUpper = lowPrice + priceBoxSize * (i + 1); double priceLower = lowPrice + priceBoxSize * i; int yUpper = GetYPos(priceUpper, bounds, min, max) + barSpacing; int yLower = GetYPos(priceLower, bounds, min, max); int barWidthUp = (int)((bounds.Width / 2) * (volumeInfo[i].up / volumeMax)); int barWidthDown = (int)((bounds.Width / 2) * (volumeInfo[i].down / volumeMax)); if (barWidthDown == int.MinValue || barWidthUp == int.MinValue) // overflow? { continue; } int barWidth = barWidthUp + barWidthDown; graphics.FillRectangle(barBrushUp, new Rectangle( bounds.X, yUpper, barWidthUp, Math.Abs(yUpper - yLower))); graphics.FillRectangle(barBrushDown, new Rectangle( bounds.X + barWidthUp, yUpper, barWidthDown, Math.Abs(yUpper - yLower))); if (drawLines == true) { // Lower line graphics.DrawLine(linePen, bounds.X, yLower, bounds.X + bounds.Width, yLower); // Upper line (only at the very top) if (i == volumeBarCount - 1) { graphics.DrawLine(linePen, bounds.X, yUpper, bounds.X + bounds.Width, yUpper); } } } }
protected override void OnBarUpdate() { /* When working with multiple bar series objects it is important to understand the sequential order in which the * OnBarUpdate() method is triggered. The bars will always run with the primary first followed by the secondary and * so on. * * Important: Primary bars will always execute before the secondary bar series. * If a bar is timestamped as 12:00PM on the 5min bar series, the call order between the equally timestamped 12:00PM * bar on the 1min bar series is like this: * 12:00PM 5min * 12:00PM 1min * 12:01PM 1min * 12:02PM 1min * 12:03PM 1min * 12:04PM 1min * 12:05PM 5min * 12:05PM 1min * * When the OnBarUpdate() is called from the primary bar series (2000 ticks series in this example), do the following */ if (BarsInProgress == 0) { if (CurrentBar < BarsRequiredToTrade) { return; } //Print("Current Bar time=" + Bars.GetTime(CurrentBar).ToString("HHmmss")); // if the bar elapsed time span across 12 mid night DateTime t1 = Bars.GetTime(CurrentBar - 1); DateTime t2 = Bars.GetTime(CurrentBar); if (TimeSpan.Compare(t1.TimeOfDay, t2.TimeOfDay) > 0) { Print("EOD Session"); HandleEOD(); string resetString = "-1"; byte[] resetMsg = Encoding.UTF8.GetBytes(resetString); // Send reset string of "-1" to the server int resetSent = sender.Send(resetMsg); lineNo = 0; //reset global flags currPos = Position.posFlat; profitChasingFlag = false; stopLossEncountered = false; return; } // prior Stop-Loss observed, construct the lineNo with special code before sending msg to the server - so that the server will flatten the position if (stopLossEncountered) { lineNo += 10000; } // construct the string buffer to be sent to DLNN string bufString = lineNo.ToString() + ',' + Bars.GetTime(CurrentBar - 1).ToString("HHmmss") + ',' + Bars.GetTime(CurrentBar).ToString("HHmmss") + ',' + Bars.GetOpen(CurrentBar).ToString() + ',' + Bars.GetClose(CurrentBar).ToString() + ',' + Bars.GetHigh(CurrentBar).ToString() + ',' + Bars.GetLow(CurrentBar).ToString() + ',' + Bars.GetVolume(CurrentBar).ToString() + ',' + SMA(9)[0].ToString() + ',' + SMA(20)[0].ToString() + ',' + SMA(50)[0].ToString() + ',' + MACD(12, 26, 9).Diff[0].ToString() + ',' + RSI(14, 3)[0].ToString() + ',' + Bollinger(2, 20).Lower[0].ToString() + ',' + Bollinger(2, 20).Upper[0].ToString() + ',' + CCI(20)[0].ToString() + ',' + Bars.GetHigh(CurrentBar).ToString() + ',' + Bars.GetLow(CurrentBar).ToString() + ',' + Momentum(20)[0].ToString() + ',' + DM(14).DiPlus[0].ToString() + ',' + DM(14).DiMinus[0].ToString() + ',' + VROC(25, 3)[0].ToString() + ',' + '0' + ',' + '0' + ',' + '0' + ',' + '0' + ',' + '0' + ',' + '0' + ',' + '0' + ',' + '0' + ',' + '0' + ',' + '0'; //Print("CurrentBar = " + CurrentBar + ": " + "bufString = " + bufString); byte[] msg = Encoding.UTF8.GetBytes(bufString); // Send the data through the socket. int bytesSent = sender.Send(msg); // Receive the response from the remote device. int bytesRec = sender.Receive(bytes); // prior Stop-Loss observed, hence ignore the returned signal from server and move on to the next bar, reset lineNo to next counter and reset stopLossEncountered flag if (stopLossEncountered) { lineNo -= 10000; lineNo++; stopLossEncountered = false; //svrSignal = ExtractResponse(System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length)); svrSignal = System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length).Split(',')[1]; Print(Bars.GetTime(CurrentBar).ToString("yyyy-MM-ddTHH:mm:ss.ffffffK") + " Ignore Post STOP-LOSS Server response= <" + svrSignal + "> Current Bar: Open=" + Bars.GetOpen(CurrentBar) + " Close=" + Bars.GetClose(CurrentBar) + " High=" + Bars.GetHigh(CurrentBar) + " Low=" + Bars.GetLow(CurrentBar)); return; } //svrSignal = ExtractResponse(System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length)); svrSignal = System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length).Split(',')[1]; Print(Bars.GetTime(CurrentBar).ToString("yyyy-MM-ddTHH:mm:ss.ffffffK") + " Server response= <" + svrSignal + "> Current Bar: Open=" + Bars.GetOpen(CurrentBar) + " Close=" + Bars.GetClose(CurrentBar) + " High=" + Bars.GetHigh(CurrentBar) + " Low=" + Bars.GetLow(CurrentBar)); //Print(Bars.GetTime(CurrentBar).ToString("yyyy-MM-ddTHH:mm:ss.ffffffK") + " Server response= <" + svrSignal + ">"); // Return signal from DLNN is not we expected, close outstanding position and restart if (bytesRec == -1) { lineNo = 0; // TODO: close current position? } else { lineNo++; } // Start processing signal after 8th signal and beyond, otherwise ignore if (lineNo >= 8) { ExecuteAITrade(svrSignal); // if position is flat, no need to do anything if (currPos == Position.posFlat) { return; } // handle stop loss or profit chasing if there is existing position and order action is either SellShort or Buy if (entryOrder != null && (entryOrder.OrderAction == OrderAction.Buy || entryOrder.OrderAction == OrderAction.SellShort) && (entryOrder.OrderState == OrderState.Filled || entryOrder.OrderState == OrderState.PartFilled)) { // if Close[0] violates soft deck, if YES handle stop loss accordingly if (ViolateSoftDeck()) { HandleSoftDeck(svrSignal); } // if profitChasingFlag is TRUE or TouchedProfitChasing then handle profit chasing if ((profitChasingFlag || TouchedProfitChasing())) { HandleProfitChasing(); } } } } // When the OnBarUpdate() is called from the secondary bar series, in our case for each tick, handle stop loss and profit chasing accordingly else { return; } }
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; }
/// <summary> /// Called on each bar update event (incoming tick) /// </summary> protected override void OnBarUpdate() { //If we are not processing the current bar, return if (CurrentBar != Bars.GetBar(DateTime.Now)) { return; } //Get current bid double bid = Bars.GetClose(Bars.GetBar(DateTime.Now)); if (previous_bid < 0) { previous_bid = bid; } IDrawObject drawing_object = DrawObjects[trendLineTag]; //Reset if drawing object is deleted or does not exist... if (drawing_object == null) { Type = null; AlertDone = false; } if (drawing_object != null && (drawing_object.DrawType == DrawType.Ray || drawing_object.DrawType == DrawType.ExtendedLine || drawing_object.DrawType == DrawType.Line)) { double y1, y2; int bar1, bar2; DateTime time1, time2; if (drawing_object.DrawType == DrawType.Ray) { IRay ray = (IRay)drawing_object; y1 = ray.Anchor1Y; y2 = ray.Anchor2Y; time1 = ray.Anchor1Time; time2 = ray.Anchor2Time; bar1 = ray.Anchor1BarsAgo; bar2 = ray.Anchor2BarsAgo; } else if (drawing_object.DrawType == DrawType.ExtendedLine) { IExtendedLine line = (IExtendedLine)drawing_object; y1 = line.StartY; y2 = line.EndY; time1 = line.StartTime; time2 = line.EndTime; bar1 = line.StartBarsAgo; bar2 = line.EndBarsAgo; } else { ILine line = (ILine)drawing_object; y1 = line.StartY; y2 = line.EndY; time1 = line.StartTime; time2 = line.EndTime; bar1 = line.StartBarsAgo; bar2 = line.EndBarsAgo; } //Reset alert if object has moved if ((time1 != this.sTime1 || time2 != this.sTime2 || y1 != this.sY1 || y2 != this.sY2) && this.sTime1 != null && this.sTime2 != null) { Type = null; AlertDone = false; } if (AlertDone == false) { //Store anchor to detect if object has moved this.sTime1 = time1; this.sTime2 = time2; this.sY1 = y1; this.sY2 = y2; //Calculate price target double y = y2 - y1; double x = bar1 - bar2; double slope = y / x; double deltaY = bar2 * slope; //time difference in ticks * slope double price_target = Math.Round(y2 + deltaY, 5); //IF price is below current price target or straddles it, THEN we alert when the bid>=price_target if (Type == null && (price_target - previous_bid) >= 0) { Type = "up"; } if (Type == null && (previous_bid - price_target) >= 0) { Type = "down"; } previous_bid = bid; if (Type == "up" && bid >= price_target) { Alert("TrendLineAlert", NinjaTrader.Cbi.Priority.High, "Reached Trend Line @ " + price_target, AlertSound, 10, Color.Black, Color.Yellow); AlertDone = true; } if (Type == "down" && bid <= price_target) { Alert("TrendLineAlert", NinjaTrader.Cbi.Priority.High, "Reached Trend Line @ " + price_target, AlertSound, 10, Color.Black, Color.Yellow); AlertDone = true; } } } }
/// <summary> /// </summary> /// <param name="bars"></param> /// <param name="open"></param> /// <param name="high"></param> /// <param name="low"></param> /// <param name="close"></param> /// <param name="time"></param> /// <param name="volume"></param> /// <param name="isRealtime"></param> public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime) { #region Building Bars from Base Period if (bars.Count != tmpCount) // reset cache when bars are trimmed if (bars.Count == 0) { tmpTime = Cbi.Globals.MinDate; tmpVolume = 0; tmpDayCount = 0; tmpTickCount = 0; } else { tmpTime = bars.GetTime(bars.Count - 1); tmpVolume = bars.GetVolume(bars.Count - 1); tmpTickCount = bars.TickCount; tmpDayCount = bars.DayCount; bars.LastPrice = bars.GetClose(bars.Count - 1); anchorPrice = bars.LastPrice; } switch (bars.Period.BasePeriodType) { case PeriodType.Day: tmpTime = time.Date; // will be modified for realtime only if (isRealtime && time >= cacheSessionEnd /* on realtime include60 is always false */) { bars.Session.GetSessionDate(time, false, out tmpTime, out cacheSessionEnd); if (tmpTime < time.Date) tmpTime = time.Date; // make sure timestamps are ascending } if (prevTime != tmpTime) tmpDayCount++; if (tmpDayCount < bars.Period.BasePeriodValue || (!isRealtime && bars.Count > 0 && tmpTime == bars.TimeLastBar.Date) || (isRealtime && bars.Count > 0 && tmpTime <= bars.TimeLastBar.Date)) endOfBar = false; else { prevTime = tmpTime; endOfBar = true; } break; case PeriodType.Minute: if (tmpTime == Cbi.Globals.MinDate) prevTime = tmpTime = TimeToBarTimeMinute(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue, isRealtime); if (!isRealtime && time <= tmpTime || isRealtime && time < tmpTime) endOfBar = false; else { prevTime = tmpTime; tmpTime = TimeToBarTimeMinute(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue, isRealtime); endOfBar = true; } break; case PeriodType.Volume: if (tmpTime == Cbi.Globals.MinDate) { tmpVolume = volume; endOfBar = tmpVolume >= bars.Period.BasePeriodValue; prevTime = tmpTime = time; if (endOfBar) tmpVolume = 0; break; } tmpVolume += volume; endOfBar = tmpVolume >= bars.Period.BasePeriodValue; if (endOfBar) { prevTime = tmpTime; tmpVolume = 0; } tmpTime = time; break; case PeriodType.Tick: if (tmpTime == Cbi.Globals.MinDate || bars.Period.BasePeriodValue == 1) { prevTime = tmpTime == Cbi.Globals.MinDate ? time : tmpTime; tmpTime = time; tmpTickCount = bars.Period.BasePeriodValue == 1 ? 0 : 1; endOfBar = bars.Period.BasePeriodValue == 1; break; } if (tmpTickCount < bars.Period.BasePeriodValue) { tmpTime = time; endOfBar = false; tmpTickCount++; } else { prevTime = tmpTime; tmpTime = time; endOfBar = true; tmpTickCount = 1; } break; case PeriodType.Month: if (tmpTime == Cbi.Globals.MinDate) prevTime = tmpTime = TimeToBarTimeMonth(time, bars.Period.BasePeriodValue); if (time.Month <= tmpTime.Month && time.Year == tmpTime.Year || time.Year < tmpTime.Year) endOfBar = false; else { prevTime = tmpTime; endOfBar = true; tmpTime = TimeToBarTimeMonth(time, bars.Period.BasePeriodValue); } break; case PeriodType.Second: if (tmpTime == Cbi.Globals.MinDate) { prevTime = tmpTime = TimeToBarTimeSecond(bars, time, new DateTime( bars.Session.NextBeginTime.Year, bars.Session.NextBeginTime.Month, bars.Session.NextBeginTime.Day, bars.Session.NextBeginTime.Hour, bars.Session.NextBeginTime.Minute, 0), bars.Period.BasePeriodValue); } if ((bars.Period.Value > 1 && time < tmpTime) || (bars.Period.Value == 1 && time <= tmpTime)) endOfBar = false; else { prevTime = tmpTime; tmpTime = TimeToBarTimeSecond(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue); endOfBar = true; } break; case PeriodType.Week: if (tmpTime == Cbi.Globals.MinDate) prevTime = tmpTime = TimeToBarTimeWeek(time.Date, tmpTime.Date, bars.Period.BasePeriodValue); if (time.Date <= tmpTime.Date) endOfBar = false; else { prevTime = tmpTime; endOfBar = true; tmpTime = TimeToBarTimeWeek(time.Date, tmpTime.Date, bars.Period.BasePeriodValue); } break; case PeriodType.Year: if (tmpTime == Cbi.Globals.MinDate) prevTime = tmpTime = TimeToBarTimeYear(time, bars.Period.Value); if (time.Year <= tmpTime.Year) endOfBar = false; else { prevTime = tmpTime; endOfBar = true; tmpTime = TimeToBarTimeYear(time, bars.Period.Value); } break; } #endregion #region Kagi Logic reversalPoint = bars.Period.ReversalType == ReversalType.Tick ? bars.Period.Value * bars.Instrument.MasterInstrument.TickSize : bars.Period.Value * 0.01 * anchorPrice; if (bars.Count == 0 || (IsIntraday && ((bars.Period.BasePeriodType != PeriodType.Second && bars.IsNewSession(time, isRealtime)) || (bars.Period.BasePeriodType == PeriodType.Second && bars.IsNewSession(tmpTime, isRealtime))))) { if (bars.Count > 0) { double lastOpen = bars.GetOpen(bars.Count - 1); double lastHigh = bars.GetHigh(bars.Count - 1); double lastLow = bars.GetLow(bars.Count - 1); double lastClose = bars.GetClose(bars.Count - 1); if (bars.Count == tmpCount) CalculateKagiBar(bars, lastOpen, lastHigh, lastLow, lastClose, prevTime, volume, isRealtime); } AddBar(bars, close, close, close, close, tmpTime, volume, isRealtime); anchorPrice = close; trend = Trend.Undetermined; prevTime = tmpTime; volumeCount = 0; bars.LastPrice = close; tmpCount = bars.Count; return; } Bar bar = (Bar)bars.Get(bars.Count - 1); double c = bar.Close; double o = bar.Open; double h = bar.High; double l = bar.Low; if (endOfBar) CalculateKagiBar(bars, o, h, l, c, prevTime, volume, isRealtime); else volumeCount += volume; bars.LastPrice = close; tmpCount = bars.Count; #endregion }
public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars) { if (chartBars.FromIndex > chartBars.ToIndex) { return; } if (chartBars.FromIndex > 0) { chartBars.FromIndex--; } Bars bars = chartBars.Bars; float barWidth = GetBarPaintWidth(BarWidthUI); int sessionStartIndex = chartBars.FromIndex; int thickOffsetTop = (int)(Stroke.Width * 0.5); int thinOffsetTop = (int)(Stroke2.Width * 0.5); Vector2 point0 = new Vector2(); Vector2 point1 = new Vector2(); while (sessionStartIndex > 0 && bars.BarsType.IsIntraday) { if (bars.BarsSeries.GetIsFirstBarOfSession(sessionStartIndex)) { break; } sessionStartIndex--; } if (sessionStartIndex < 0) // Occurs when all bars are off screen { return; } thickLine = bars.GetClose(sessionStartIndex) > bars.GetOpen(sessionStartIndex); //Determine the next bar coming up is thick or thin for (int k = sessionStartIndex + 1; k < chartBars.FromIndex; k++) { double closeTest = bars.GetClose(k); if (closeTest > bars.GetOpen(k)) { if (Math.Max(bars.GetOpen(k - 1), bars.GetClose(k - 1)) < closeTest) { thickLine = true; } } else if (closeTest < Math.Min(bars.GetOpen(k - 1), bars.GetClose(k - 1))) { thickLine = false; } } for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++) { Brush overriddenBrush = chartControl.GetBarOverrideBrush(chartBars, idx); double openValue = bars.GetOpen(idx); float open = chartScale.GetYByValue(openValue); double closeValue = bars.GetClose(idx); float close = chartScale.GetYByValue(closeValue); float x = chartControl.GetXByBarIndex(chartBars, idx); double prevOpenValue = idx == 0 ? openValue : bars.GetOpen(idx - 1); double prevCloseValue = idx == 0 ? closeValue : bars.GetClose(idx - 1); float startPosition; if (idx == 0 && chartBars.ToIndex >= 1) { float x0 = chartControl.GetXByBarIndex(chartBars, 0); float x1 = chartControl.GetXByBarIndex(chartBars, 1); float diffX = Math.Max(1, x1 - x0); startPosition = x0 - diffX; } else { startPosition = idx == chartBars.FromIndex ? chartControl.GetXByBarIndex(chartBars, idx) : chartControl.GetXByBarIndex(chartBars, idx - 1); } startPosition = startPosition < 0 ? 0 : startPosition; if (bars.BarsType.IsIntraday && bars.IsResetOnNewTradingDay && bars.BarsSeries.GetIsFirstBarOfSession(idx)) { // First bar if (closeValue > openValue) { point0.X = x; point0.Y = open; point1.X = x; point1.Y = close; TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle); thickLine = true; } else { point0.X = x; point0.Y = open; point1.X = x; point1.Y = close; TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle); thickLine = false; } } else { if (closeValue > openValue) { if (closeValue <= Math.Max(prevCloseValue, prevOpenValue)) { // Maintain previous thickness if (thickLine) { point0.X = x; point0.Y = open + thickOffsetTop; point1.X = x; point1.Y = close - thickOffsetTop; TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle); point0.X = startPosition; point0.Y = open; point1.X = x; point1.Y = open; TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle); } else { point0.X = x; point0.Y = open + thinOffsetTop; point1.X = x; point1.Y = close - thinOffsetTop; TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle); point0.X = startPosition; point0.Y = open; point1.X = x; point1.Y = open; TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle); } } else if (closeValue > Math.Max(prevCloseValue, prevOpenValue)) { double transitionPoint = Math.Max(prevCloseValue, prevOpenValue); point0.X = x; point0.Y = close - thickOffsetTop; point1.X = x; point1.Y = chartScale.GetYByValue(transitionPoint); TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); RenderTarget.DrawLine(point0, point1, Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle); point0.X = x; point0.Y = chartScale.GetYByValue(transitionPoint); point1.X = x; point1.Y = open + (thickLine ? thickOffsetTop : thinOffsetTop); TransformBrush(overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), new RectangleF(point0.X, point0.Y - (thickLine ? Stroke.Width : Stroke2.Width), barWidth, thickLine ? Stroke.Width : Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), thickLine ? Stroke.Width : Stroke2.Width, thickLine ? Stroke.StrokeStyle : Stroke2.StrokeStyle); point0.X = startPosition; point0.Y = open; point1.X = x; point1.Y = open; TransformBrush(overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), new RectangleF(point0.X, point0.Y - (thickLine ? Stroke.Width : Stroke2.Width), barWidth, thickLine ? Stroke.Width : Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), thickLine ? Stroke.Width : Stroke2.Width, thickLine ? Stroke.StrokeStyle : Stroke2.StrokeStyle); thickLine = true; } } else { if (Math.Min(prevCloseValue, prevOpenValue) <= closeValue) { // Maintain previous thickness if (thickLine) { point0.X = x; point0.Y = open - thickOffsetTop; point1.X = x; point1.Y = close + thickOffsetTop; TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle); point0.X = startPosition; point0.Y = open; point1.X = x; point1.Y = open; TransformBrush(overriddenBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle); } else { point0.X = x; point0.Y = open - thinOffsetTop; point1.X = x; point1.Y = close + thinOffsetTop; TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle); point0.X = startPosition; point0.Y = open; point1.X = x; point1.Y = open; TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle); } } else if (closeValue < Math.Min(prevCloseValue, prevOpenValue)) { double transitionPoint = Math.Min(prevCloseValue, prevOpenValue); point0.X = startPosition; point0.Y = open; point1.X = x; point1.Y = open; TransformBrush(overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), new RectangleF(point0.X, point0.Y - (thickLine ? Stroke.Width : Stroke2.Width), barWidth, thickLine ? Stroke.Width : Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), thickLine ? Stroke.Width : Stroke2.Width, thickLine ? Stroke.StrokeStyle : Stroke2.StrokeStyle); point0.X = x; point0.Y = open - (thickLine ? thickOffsetTop : thinOffsetTop); point1.X = x; point1.Y = chartScale.GetYByValue(transitionPoint); TransformBrush(overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), new RectangleF(point0.X, point0.Y - (thickLine ? Stroke.Width : Stroke2.Width), barWidth, thickLine ? Stroke.Width : Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? (thickLine ? Stroke.BrushDX : Stroke2.BrushDX), thickLine ? Stroke.Width : Stroke2.Width, thickLine ? Stroke.StrokeStyle : Stroke2.StrokeStyle); point0.X = x; point0.Y = chartScale.GetYByValue(transitionPoint); point1.X = x; point1.Y = close + thinOffsetTop; TransformBrush(overriddenBrush ?? Stroke2.BrushDX, new RectangleF(point0.X, point0.Y - Stroke2.Width, barWidth, Stroke2.Width)); RenderTarget.DrawLine(point0, point1, overriddenBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle); thickLine = false; } } } } }
public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars) { Bars bars = chartBars.Bars; float barWidth = GetBarPaintWidth(BarWidthUI); Vector2 point0 = new Vector2(); Vector2 point1 = new Vector2(); RectangleF rect = new RectangleF(); for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++) { Brush overriddenBarBrush = chartControl.GetBarOverrideBrush(chartBars, idx); Brush overriddenOutlineBrush = chartControl.GetCandleOutlineOverrideBrush(chartBars, idx); double closeValue = bars.GetClose(idx); int close = chartScale.GetYByValue(closeValue); int high = chartScale.GetYByValue(bars.GetHigh(idx)); int low = chartScale.GetYByValue(bars.GetLow(idx)); double openValue = bars.GetOpen(idx); int open = chartScale.GetYByValue(openValue); int x = chartControl.GetXByBarIndex(chartBars, idx); if (Math.Abs(open - close) < 0.0000001) { // Line point0.X = x - barWidth * 0.5f; point0.Y = close; point1.X = x + barWidth * 0.5f; point1.Y = close; Brush b = overriddenOutlineBrush ?? Stroke.BrushDX; if (!(b is SolidColorBrush)) { TransformBrush(overriddenOutlineBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width)); } RenderTarget.DrawLine(point0, point1, b, Stroke.Width, Stroke.StrokeStyle); } else { // Candle rect.X = x - barWidth * 0.5f + 0.5f; rect.Y = Math.Min(close, open); rect.Width = barWidth - 1; rect.Height = Math.Max(open, close) - Math.Min(close, open); Brush brush = overriddenBarBrush ?? (closeValue >= openValue ? UpBrushDX : DownBrushDX); if (!(brush is SolidColorBrush)) { TransformBrush(brush, rect); } RenderTarget.FillRectangle(rect, brush); brush = overriddenOutlineBrush ?? Stroke.BrushDX; if (!(brush is SolidColorBrush)) { TransformBrush(brush, rect); } RenderTarget.DrawRectangle(rect, overriddenOutlineBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle); } Brush br = overriddenOutlineBrush ?? Stroke2.BrushDX; // High wick if (high < Math.Min(open, close)) { point0.X = x; point0.Y = high; point1.X = x; point1.Y = Math.Min(open, close); if (!(br is SolidColorBrush)) { TransformBrush(br, new RectangleF(point0.X - Stroke2.Width, point0.Y, Stroke2.Width, point1.Y - point0.Y)); } RenderTarget.DrawLine(point0, point1, br, Stroke2.Width, Stroke2.StrokeStyle); } // Low wick if (low > Math.Max(open, close)) { point0.X = x; point0.Y = low; point1.X = x; point1.Y = Math.Max(open, close); if (!(br is SolidColorBrush)) { TransformBrush(br, new RectangleF(point1.X - Stroke2.Width, point1.Y, Stroke2.Width, point0.Y - point1.Y)); } RenderTarget.DrawLine(point0, point1, br, Stroke2.Width, Stroke2.StrokeStyle); } } }
private void printAuswertung() { decimal GapTradeResult; Color colorTextBox; string strResultDescr = ""; GapTradeResult = (decimal)Bars.GetClose(ProcessingBarIndex - 1) - (decimal)Bars.GetOpen(ProcessingBarIndex - 1); if (GapTradeLong == true) { //Long GapTradeCounterLong += 1; GapTradeResultTotalLong = GapTradeResultTotalLong + GapTradeResult; string strGapeTradeLong = "GapTradeLong" + ProcessingBarIndex; string strTradeResultLong; TradeDir = "Long"; if (GapTradeResult < 0) { if (_print_info == true) { Print("Fail"); } GapTradeFailCounterLong += 1; strResultDescr = "Fail"; strTradeResultLong = "Fail " + GapTradeResult.ToString(); colorTextBox = colFail; } else { GapTradeWinCounterLong += 1; strResultDescr = "Win"; strTradeResultLong = "Win " + GapTradeResult.ToString(); colorTextBox = colWin; } AddChartText(strGapeTradeLong, true, strTradeResultLong, Time[1], Bars.GetHigh(ProcessingBarIndex - 1) + (100 * TickSize), 9, Color.Black, new Font("Arial", 9), StringAlignment.Center, Color.Black, colorTextBox, 70); } else if (GapTradeShort == true) { //Short GapTradeCounterShort += 1; GapTradeResultTotalShort = GapTradeResultTotalShort + GapTradeResult; string strGapeTradeShort = "GapTradeLong" + ProcessingBarIndex; string strTradeResultShort; TradeDir = "Short"; if (GapTradeResult > 0) { if (_print_info == true) { Print("Fail"); } GapTradeFailCounterShort += 1; strResultDescr = "Fail"; strTradeResultShort = "Fail " + GapTradeResult.ToString(); colorTextBox = colFail; } else { GapTradeWinCounterShort += 1; strResultDescr = "Win"; strTradeResultShort = "Win " + GapTradeResult.ToString(); colorTextBox = colWin; } AddChartText(strGapeTradeShort, true, strTradeResultShort, Time[1], Bars.GetLow(ProcessingBarIndex - 1) - (100 * TickSize), 9, Color.Black, new Font("Arial", 9), StringAlignment.Center, Color.Black, colorTextBox, 70); } if (_print_info == true) { Print("Gap Trade Result: " + GapTradeResult); } if (dev_mode == true) { Print(Instrument.Name + ";" + Math.Round(GapSize, 2) + ";" + GapTradeResult + ";" + strResultDescr + ";" + TradeDir); } }
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; }
protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask) { if (SessionIterator == null) { SessionIterator = new SessionIterator(bars); } offset = bars.BarsPeriod.Value * bars.Instrument.MasterInstrument.TickSize; bool isNewSession = SessionIterator.IsNewSession(time, isBar); if (isNewSession) { SessionIterator.GetNextSession(time, isBar); } if (bars.Count == 0 || bars.IsResetOnNewTradingDay && isNewSession) { if (bars.Count > 0) { // Close out last bar in session and set open == close double lastBarClose = bars.GetClose(bars.Count - 1); DateTime lastBarTime = bars.GetTime(bars.Count - 1); long lastBarVolume = bars.GetVolume(bars.Count - 1); RemoveLastBar(bars); AddBar(bars, lastBarClose, lastBarClose, lastBarClose, lastBarClose, lastBarTime, lastBarVolume); } renkoHigh = close + offset; renkoLow = close - offset; isNewSession = SessionIterator.IsNewSession(time, isBar); if (isNewSession) { SessionIterator.GetNextSession(time, isBar); } AddBar(bars, close, close, close, close, time, volume); bars.LastPrice = close; return; } double barOpen = bars.GetOpen(bars.Count - 1); double barHigh = bars.GetHigh(bars.Count - 1); double barLow = bars.GetLow(bars.Count - 1); long barVolume = bars.GetVolume(bars.Count - 1); DateTime barTime = bars.GetTime(bars.Count - 1); if (renkoHigh.ApproxCompare(0.0) == 0 || renkoLow.ApproxCompare(0.0) == 0) { if (bars.Count == 1) { renkoHigh = barOpen + offset; renkoLow = barOpen - offset; } else if (bars.GetClose(bars.Count - 2) > bars.GetOpen(bars.Count - 2)) { renkoHigh = bars.GetClose(bars.Count - 2) + offset; renkoLow = bars.GetClose(bars.Count - 2) - offset * 2; } else { renkoHigh = bars.GetClose(bars.Count - 2) + offset * 2; renkoLow = bars.GetClose(bars.Count - 2) - offset; } } if (close.ApproxCompare(renkoHigh) >= 0) { if (barOpen.ApproxCompare(renkoHigh - offset) != 0 || barHigh.ApproxCompare(Math.Max(renkoHigh - offset, renkoHigh)) != 0 || barLow.ApproxCompare(Math.Min(renkoHigh - offset, renkoHigh)) != 0) { RemoveLastBar(bars); AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, renkoHigh), Math.Min(renkoHigh - offset, renkoHigh), renkoHigh, barTime, barVolume); } renkoLow = renkoHigh - 2.0 * offset; renkoHigh = renkoHigh + offset; isNewSession = SessionIterator.IsNewSession(time, isBar); if (isNewSession) { SessionIterator.GetNextSession(time, isBar); } while (close.ApproxCompare(renkoHigh) >= 0) // Add empty bars to fill gap if price jumps { AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, renkoHigh), Math.Min(renkoHigh - offset, renkoHigh), renkoHigh, time, 0); renkoLow = renkoHigh - 2.0 * offset; renkoHigh = renkoHigh + offset; } // Add final partial bar AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, close), Math.Min(renkoHigh - offset, close), close, time, volume); } else if (close.ApproxCompare(renkoLow) <= 0) { if (barOpen.ApproxCompare(renkoLow + offset) != 0 || barHigh.ApproxCompare(Math.Max(renkoLow + offset, renkoLow)) != 0 || barLow.ApproxCompare(Math.Min(renkoLow + offset, renkoLow)) != 0) { RemoveLastBar(bars); AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, barTime, barVolume); } renkoHigh = renkoLow + 2.0 * offset; renkoLow = renkoLow - offset; isNewSession = SessionIterator.IsNewSession(time, isBar); if (isNewSession) { SessionIterator.GetNextSession(time, isBar); } while (close.ApproxCompare(renkoLow) <= 0) // Add empty bars to fill gap if price jumps { AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, time, 0); renkoHigh = renkoLow + 2.0 * offset; renkoLow = renkoLow - offset; } // Add final partial bar AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, close), Math.Min(renkoLow + offset, close), close, time, volume); } else { UpdateBar(bars, close, close, close, time, volume); } bars.LastPrice = close; }
protected override void OnBarUpdate() { switch (pOrT) { case PriceOrTime.Price: { MAX_HIGH = Math.Max(MAX_HIGH, High[0]); MIN_LOW = Math.Min(MIN_LOW, Low[0]); if (CurrentBar == Bars.Count - 2) { MAX_HIGH = Math.Round(MAX_HIGH * 1.05, PriceDigits); MIN_LOW = Math.Round(MIN_LOW * 0.95, PriceDigits); if (InitialPrice < MIN_LOW || InitialPrice > MAX_HIGH) { Log("InitialPrice parameter MUST be between the high price and low price on this chart", NinjaTrader.Cbi.LogLevel.Information); if (InitialPrice > MAX_HIGH) { InitialPrice = MAX_HIGH; } if (InitialPrice < MIN_LOW) { InitialPrice = MIN_LOW; } } double LevelUp = -1.0, LevelDown = -1.0; i = 1; do { if (Angle000Flag) { LevelUp = InitialPrice + Angle0[i] * TickSize * MultiplierForPriceScale; LevelDown = InitialPrice - Angle0[i] * TickSize * MultiplierForPriceScale; MakePriceLine(LevelUp, LevelDown, Color0); } if (Angle090Flag) { LevelUp = InitialPrice + Angle90[i] * TickSize * MultiplierForPriceScale; LevelDown = InitialPrice - Angle90[i] * TickSize * MultiplierForPriceScale; MakePriceLine(LevelUp, LevelDown, Color90); } if (Angle180Flag) { LevelUp = InitialPrice + Angle180[i] * TickSize * MultiplierForPriceScale; LevelDown = InitialPrice - Angle180[i] * TickSize * MultiplierForPriceScale; MakePriceLine(LevelUp, LevelDown, Color180); } if (Angle270Flag) { LevelUp = InitialPrice + Angle270[i] * TickSize * MultiplierForPriceScale; LevelDown = InitialPrice - Angle270[i] * TickSize * MultiplierForPriceScale; MakePriceLine(LevelUp, LevelDown, Color270); } i++; if (LevelUp < 0.0 || LevelDown < 0.0) { break; } if (i >= Angle0.Length) { break; } if (i >= Angle90.Length) { break; } if (i >= Angle180.Length) { break; } if (i >= Angle270.Length) { break; } if (LevelUp > MaxLevelUp) { MaxLevelUp = LevelUp; } if (LevelDown < MinLevelDown) { MinLevelDown = LevelDown; } }while (1 == 1); } break; } case PriceOrTime.Time: { if (ZuluTime.CompareTo(Time[0]) < 0 && ZuluBar < 0) { ZuluBar = CurrentBar; //set ZuluBar to time the user selected } Print("Zulubar" + ZuluBar.ToString()); if (ZuluBar > 0) { OutString = null; if (Angle000Flag) { i = Angle0[NextBar0] + ZuluBar; if (i == CurrentBar) { MakeVerticalLine(0, Color0); NextBar0++; } OutString = "Zero line coming in " + (i - CurrentBar).ToString() + " bars" + Environment.NewLine; } if (Angle090Flag) { i = Angle90[NextBar90] + ZuluBar; if (i == CurrentBar) { MakeVerticalLine(0, Color90); NextBar90++; } OutString = OutString + "90 line coming in " + (i - CurrentBar).ToString() + " bars" + Environment.NewLine; } if (Angle180Flag) { i = Angle180[NextBar180] + ZuluBar; if (i == CurrentBar) { MakeVerticalLine(0, Color180); NextBar180++; } OutString = OutString + "180 line coming in " + (i - CurrentBar).ToString() + " bars" + Environment.NewLine; } if (Angle270Flag) { i = Angle270[NextBar270] + ZuluBar; if (i == CurrentBar) { MakeVerticalLine(0, Color270); NextBar270++; } OutString = OutString + "270 line coming in " + (i - CurrentBar).ToString() + " bars"; } if (OutString.Length > 0 && DisplayCountDown) { lastBar = Math.Min(ChartControl.LastSlotPainted, Bars.Count - 1); firstBar = (lastBar - ChartControl.SlotsPainted) + 1; int i; // Find highest and lowest price points HighestPaintedPrice = double.MinValue; LowestPaintedPrice = double.MaxValue; for (i = firstBar; i <= lastBar && i >= 0; i++) { HighestPaintedPrice = Math.Max(HighestPaintedPrice, Bars.GetHigh(i)); LowestPaintedPrice = Math.Min(LowestPaintedPrice, Bars.GetLow(i)); } double Outprice = (HighestPaintedPrice + LowestPaintedPrice) / 2.0; if (Bars.GetClose(lastBar - 1) < Outprice) { Outprice = HighestPaintedPrice; } if (Bars.GetClose(lastBar - 1) >= Outprice) { Outprice = (Outprice + LowestPaintedPrice) / 2.0; } Print(OutString); NinjaTrader.Gui.Tools.SimpleFont myFont = new NinjaTrader.Gui.Tools.SimpleFont("Arial", 10) { Size = 20, Bold = false }; if (CurrentBar > 10) { Draw.Text(this, "Info", true, OutString, 10, Outprice, 0, Brushes.Gray, myFont, TextAlignment.Justify, Brushes.White, Brushes.Transparent, 50); } } } break; } } }
/// <summary> /// </summary> /// <param name="bars"></param> /// <param name="open"></param> /// <param name="high"></param> /// <param name="low"></param> /// <param name="close"></param> /// <param name="time"></param> /// <param name="volume"></param> /// <param name="isRealtime"></param> public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime) { #region Building Bars from Base Period if (bars.Count != tmpCount) // reset cache when bars are trimmed { if (bars.Count == 0) { tmpTime = Cbi.Globals.MinDate; tmpVolume = 0; tmpDayCount = 0; tmpTickCount = 0; } else { tmpTime = bars.GetTime(bars.Count - 1); tmpVolume = bars.GetVolume(bars.Count - 1); tmpTickCount = bars.TickCount; tmpDayCount = bars.DayCount; bars.LastPrice = anchorPrice = bars.GetClose(bars.Count - 1); } } switch (bars.Period.BasePeriodType) { case PeriodType.Day: if (bars.Count == 0) { if (isRealtime && bars.Session.SessionsOfDay.Length > 0) { DateTime barTime; bars.Session.GetSessionDate(time, false, out barTime, out cacheSessionEnd); AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, barTime, volume, true); } else { AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time.Date, volume, isRealtime); } } else { DateTime barTime; if (!isRealtime) { barTime = time.Date; } else if (time >= cacheSessionEnd /* on realtime include60 is always false */) { bars.Session.GetSessionDate(time, false, out barTime, out cacheSessionEnd); if (barTime < bars.TimeLastBar.Date) { barTime = bars.TimeLastBar.Date; // make sure timestamps are ascending } } else { barTime = bars.TimeLastBar.Date; // make sure timestamps are ascending } if (bars.DayCount < bars.Period.Value || (!isRealtime && bars.Count > 0 && barTime == bars.TimeLastBar.Date) || (isRealtime && bars.Count > 0 && barTime <= bars.TimeLastBar.Date)) { UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, barTime, volume, isRealtime); } else { AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, barTime, volume, isRealtime); } } break; case PeriodType.Minute: if (bars.Count == 0) { AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, TimeToBarTimeMinute(bars, time, bars.Session.NextBeginTime, bars.Period.Value, isRealtime), volume, isRealtime); } else { if (isRealtime && time < bars.TimeLastBar) { UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, bars.TimeLastBar, volume, true); } else if (!isRealtime && time <= bars.TimeLastBar) { UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, bars.TimeLastBar, volume, false); } else { time = TimeToBarTimeMinute(bars, time, bars.Session.NextBeginTime, bars.Period.Value, isRealtime); AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, volume, isRealtime); } } break; case PeriodType.Volume: if (bars.Count == 0) { while (volume > bars.Period.Value) { AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, bars.Period.Value, isRealtime); volume -= bars.Period.Value; } if (volume > 0) { AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, volume, isRealtime); } } else { long volumeTmp = 0; if (!bars.IsNewSession(time, isRealtime)) { volumeTmp = Math.Min(bars.Period.Value - bars.GetVolume(bars.Count - 1), volume); if (volumeTmp > 0) { UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, volumeTmp, isRealtime); } } volumeTmp = volume - volumeTmp; while (volumeTmp > 0) { AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, Math.Min(volumeTmp, bars.Period.Value), isRealtime); volumeTmp -= bars.Period.Value; } } break; case PeriodType.Month: if (bars.Count == 0) { AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, TimeToBarTimeMonth(time, bars.Period.Value), volume, isRealtime); } else { if ((time.Month <= bars.TimeLastBar.Month && time.Year == bars.TimeLastBar.Year) || time.Year < bars.TimeLastBar.Year) { UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, bars.TimeLastBar, volume, isRealtime); } else { AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, TimeToBarTimeMonth(time, bars.Period.Value), volume, isRealtime); } } break; case PeriodType.Second: if (bars.Count == 0) { AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, TimeToBarTimeSecond(bars, time, new DateTime(bars.Session.NextBeginTime.Year, bars.Session.NextBeginTime.Month, bars.Session.NextBeginTime.Day, bars.Session.NextBeginTime.Hour, bars.Session.NextBeginTime.Minute, 0), bars.Period.Value), volume, isRealtime); } else { if ((bars.Period.Value > 1 && time < bars.TimeLastBar) || (bars.Period.Value == 1 && time <= bars.TimeLastBar)) { UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, bars.TimeLastBar, volume, isRealtime); } else { time = TimeToBarTimeSecond(bars, time, bars.Session.NextBeginTime, bars.Period.Value); AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, volume, isRealtime); } } break; case PeriodType.Tick: if (bars.Count == 0) { AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, volume, isRealtime); } else { if (bars.Count > 0 && !bars.IsNewSession(time, isRealtime) && bars.Period.Value > 1 && bars.TickCount < bars.Period.Value) { UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, volume, isRealtime); } else { AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, time, volume, isRealtime); } } break; case PeriodType.Week: if (bars.Count == 0) { AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, TimeToBarTimeWeek(time, time.AddDays((6 - (((int)time.DayOfWeek + 1) % 7)) + ((bars.Period.Value - 1) * 7)), bars.Period.Value), volume, isRealtime); } else if (time.Date <= bars.TimeLastBar.Date) { UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, bars.TimeLastBar, volume, isRealtime); } else { AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, TimeToBarTimeWeek(time.Date, bars.TimeLastBar.Date, bars.Period.Value), volume, isRealtime); } break; case PeriodType.Year: if (bars.Count == 0) { AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, TimeToBarTimeYear(time, bars.Period.Value), volume, isRealtime); } else { if (time.Year <= bars.TimeLastBar.Year) { UpdateBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, bars.TimeLastBar, volume, isRealtime); } else { AddBar(bars, 0 - open, 0 - low, 0 - high, 0 - close, TimeToBarTimeYear(time.Date, bars.Period.Value), volume, isRealtime); } } break; default: break; } #endregion }
public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars) { Bars bars = chartBars.Bars; if (chartBars.FromIndex > 0) { chartBars.FromIndex--; } SharpDX.Direct2D1.PathGeometry lineGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory); AntialiasMode oldAliasMode = RenderTarget.AntialiasMode; GeometrySink sink = lineGeometry.Open(); sink.BeginFigure(new Vector2(chartControl.GetXByBarIndex(chartBars, chartBars.FromIndex > -1 ? chartBars.FromIndex : 0), chartScale.GetYByValue(bars.GetClose(chartBars.FromIndex > -1 ? chartBars.FromIndex : 0))), FigureBegin.Filled); for (int idx = chartBars.FromIndex + 1; idx <= chartBars.ToIndex; idx++) { double closeValue = bars.GetClose(idx); float close = chartScale.GetYByValue(closeValue); float x = chartControl.GetXByBarIndex(chartBars, idx); sink.AddLine(new Vector2(x, close)); } sink.EndFigure(FigureEnd.Open); sink.Close(); RenderTarget.AntialiasMode = AntialiasMode.PerPrimitive; RenderTarget.DrawGeometry(lineGeometry, UpBrushDX, (float)Math.Max(1, chartBars.Properties.ChartStyle.BarWidth)); lineGeometry.Dispose(); SharpDX.Direct2D1.SolidColorBrush fillOutline = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.Transparent); SharpDX.Direct2D1.PathGeometry fillGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory); GeometrySink fillSink = fillGeometry.Open(); fillSink.BeginFigure(new Vector2(chartControl.GetXByBarIndex(chartBars, chartBars.FromIndex > -1 ? chartBars.FromIndex : 0), chartScale.GetYByValue(chartScale.MinValue)), FigureBegin.Filled); float fillx = float.NaN; for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++) { double closeValue = bars.GetClose(idx); float close = chartScale.GetYByValue(closeValue); fillx = chartControl.GetXByBarIndex(chartBars, idx); fillSink.AddLine(new Vector2(fillx, close)); } if (!double.IsNaN(fillx)) { fillSink.AddLine(new Vector2(fillx, chartScale.GetYByValue(chartScale.MinValue))); } fillSink.EndFigure(FigureEnd.Open); fillSink.Close(); DownBrushDX.Opacity = Opacity / 100f; if (!(DownBrushDX is SharpDX.Direct2D1.SolidColorBrush)) { TransformBrush(DownBrushDX, new RectangleF(0, 0, (float)chartScale.Width, (float)chartScale.Height)); } RenderTarget.FillGeometry(fillGeometry, DownBrushDX); RenderTarget.DrawGeometry(fillGeometry, fillOutline, (float)chartBars.Properties.ChartStyle.BarWidth); fillOutline.Dispose(); RenderTarget.AntialiasMode = oldAliasMode; fillGeometry.Dispose(); }
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; }
public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars) { Bars bars = chartBars.Bars; float chartMinX = ConvertToHorizontalPixels(chartControl, chartControl.CanvasLeft + chartControl.Properties.BarMarginRight); RectangleF rect = new RectangleF(); int toIndex = chartBars.ToIndex; if (toIndex >= 0 && toIndex < bars.Count - 1) { toIndex++; } for (int idx = chartBars.FromIndex; idx <= toIndex; idx++) { double closeValue = bars.GetClose(idx); float high = chartScale.GetYByValue(bars.GetHigh(idx)); float low = chartScale.GetYByValue(bars.GetLow(idx)); double openValue = bars.GetOpen(idx); Brush overriddenBarBrush = chartControl.GetBarOverrideBrush(chartBars, idx); Brush overriddenOutlineBrush = chartControl.GetCandleOutlineOverrideBrush(chartBars, idx); float x = chartControl.GetXByBarIndex(chartBars, idx); float boxStartPosition; if (idx == chartBars.FromIndex && (toIndex == 0 || idx == 0)) { if (toIndex == 0) { boxStartPosition = chartMinX; } else { boxStartPosition = 2 * x - chartControl.GetXByBarIndex(chartBars, idx + 1); } } else { boxStartPosition = chartControl.GetXByBarIndex(chartBars, idx - 1); } if (Math.Abs(x - boxStartPosition) < 0.2) { continue; } float width = Math.Max(2f, Math.Abs(x - boxStartPosition)); if (closeValue > openValue) { width -= Stroke.Width; rect.X = boxStartPosition; rect.Y = high; rect.Width = width; rect.Height = low - high; TransformBrush(overriddenBarBrush ?? UpBrushDX, rect); TransformBrush(overriddenOutlineBrush ?? Stroke.BrushDX, rect); RenderTarget.FillRectangle(rect, overriddenBarBrush ?? UpBrushDX); RenderTarget.DrawRectangle(rect, overriddenOutlineBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle); } else { width -= Stroke2.Width; rect.X = boxStartPosition; rect.Y = high; rect.Width = width; rect.Height = low - high; TransformBrush(overriddenBarBrush ?? DownBrushDX, rect); TransformBrush(overriddenOutlineBrush ?? Stroke2.BrushDX, rect); RenderTarget.FillRectangle(rect, overriddenBarBrush ?? DownBrushDX); RenderTarget.DrawRectangle(rect, overriddenOutlineBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle); } } }
protected override void OnRender(ChartControl chartControl, ChartScale chartScale) { if (IsInHitTest) { return; } int lastBar = ChartBars.ToIndex; int firstBar = ChartBars.FromIndex; double highPrice = 0; double lowPrice = double.MaxValue; SharpDX.Direct2D1.Brush brushDown = BarDownBrush.ToDxBrush(RenderTarget); SharpDX.Direct2D1.Brush lineBrush = LineBrush.ToDxBrush(RenderTarget); SharpDX.Direct2D1.Brush brushUp = BarUpBrush.ToDxBrush(RenderTarget); brushDown.Opacity = (float)(Opacity / 100.0); brushUp.Opacity = (float)(Opacity / 100.0); for (int idx = firstBar; idx <= lastBar && idx >= 0; idx++) { highPrice = Math.Max(highPrice, Bars.GetHigh(idx)); lowPrice = Math.Min(lowPrice, Bars.GetLow(idx)); } int volumeBarCount = BarCount; double priceRange = highPrice - lowPrice; double priceBoxSize = priceRange / volumeBarCount; double volumeMax = 0; // Pass 1: Fill all VolumeInfo structures with appropriate data for (int i = 0; i < volumeBarCount; i++) { double priceUpper = lowPrice + priceBoxSize * (i + 1); double priceLower = lowPrice + priceBoxSize * i; double priceVolumeUp = 0; double priceVolumeDown = 0; for (int idx = firstBar; idx <= lastBar; idx++) { double checkPrice; PriceSeries series = (Inputs[0] as PriceSeries); switch (series.PriceType) { case PriceType.Open: checkPrice = Bars.GetOpen(idx); break; case PriceType.Close: checkPrice = Bars.GetClose(idx); break; case PriceType.High: checkPrice = Bars.GetHigh(idx); break; case PriceType.Low: checkPrice = Bars.GetLow(idx); break; case PriceType.Median: checkPrice = (Bars.GetHigh(idx) + Bars.GetLow(idx)) / 2; break; case PriceType.Typical: checkPrice = (Bars.GetHigh(idx) + Bars.GetLow(idx) + Bars.GetClose(idx)) / 3; break; case PriceType.Weighted: checkPrice = (Bars.GetHigh(idx) + Bars.GetLow(idx) + 2 * Bars.GetClose(idx)) / 4; break; default: checkPrice = Bars.GetClose(idx); break; } if (checkPrice >= priceLower && checkPrice < priceUpper) { if (Bars.GetOpen(idx) < Bars.GetClose(idx)) { priceVolumeUp += Bars.GetVolume(idx); } else { priceVolumeDown += Bars.GetVolume(idx); } } } volumeInfo[i].up = priceVolumeUp; volumeInfo[i].down = priceVolumeDown; volumeInfo[i].total = priceVolumeUp + priceVolumeDown; volumeMax = Math.Max(volumeMax, volumeInfo[i].total); } // Pass 2: Paint the volume bars for (int i = 0; i < Math.Min(volumeBarCount, lastBar - firstBar + 1); i++) { double priceUpper = lowPrice + priceBoxSize * (i + 1); double priceLower = lowPrice + priceBoxSize * i; int yUpper = Convert.ToInt32(chartScale.GetYByValue(priceUpper)) + BarSpacing; int yLower = Convert.ToInt32(chartScale.GetYByValue(priceLower)); int barWidthUp = (int)((chartScale.Height / 2) * (volumeInfo[i].up / volumeMax)); int barWidthDown = (int)((chartScale.Height / 2) * (volumeInfo[i].down / volumeMax)); SharpDX.RectangleF rect = new SharpDX.RectangleF(ChartPanel.X, yUpper, barWidthUp, Math.Abs(yUpper - yLower)); RenderTarget.FillRectangle(rect, brushUp); RenderTarget.DrawRectangle(rect, brushUp); SharpDX.RectangleF rect2 = new SharpDX.RectangleF(ChartPanel.X + barWidthUp, yUpper, barWidthDown, Math.Abs(yUpper - yLower)); RenderTarget.DrawRectangle(rect2, brushDown); RenderTarget.FillRectangle(rect2, brushDown); if (DrawLines) { RenderTarget.DrawLine(new SharpDX.Vector2(ChartPanel.X, yLower), new SharpDX.Vector2(ChartPanel.X + ChartPanel.W, yLower), lineBrush); if (i == volumeBarCount - 1) { RenderTarget.DrawLine(new SharpDX.Vector2(ChartPanel.X, yUpper), new SharpDX.Vector2(ChartPanel.X + ChartPanel.W, yUpper), lineBrush); } } } lineBrush.Dispose(); brushDown.Dispose(); brushUp.Dispose(); }
/// <summary> /// </summary> /// <param name="bars"></param> /// <param name="open"></param> /// <param name="high"></param> /// <param name="low"></param> /// <param name="close"></param> /// <param name="time"></param> /// <param name="volume"></param> /// <param name="isRealtime"></param> public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime) { offset = bars.Period.Value * bars.Instrument.MasterInstrument.TickSize; if (bars.Count < tmpCount && bars.Count > 0) // reset cache when bars are trimmed { renkoHigh = bars.GetClose(bars.Count - 1) + offset; renkoLow = bars.GetClose(bars.Count - 1) - offset; } if ((bars.Count == 0) || (bars.IsNewSession(time, isRealtime))) { if (bars.Count != 0) { // close out last bar in session and set open == close Bar lastBar = (Bar)bars.Get(bars.Count - 1); bars.RemoveLastBar(isRealtime); // Note: bar is now just a local var and not in series! AddBar(bars, lastBar.Close, lastBar.Close, lastBar.Close, lastBar.Close, lastBar.Time, lastBar.Volume, isRealtime); } renkoHigh = close + offset; renkoLow = close - offset; AddBar(bars, close, close, close, close, time, volume, isRealtime); bars.LastPrice = close; return; } Bar bar = (Bar)bars.Get(bars.Count - 1); if (renkoHigh == 0 || renkoLow == 0) //Not sure why, but happens { if (bars.Count == 1) { renkoHigh = bar.Open + offset; renkoLow = bar.Open - offset; } else if (bars.GetClose(bars.Count - 2) > bars.GetOpen(bars.Count - 2)) { renkoHigh = bars.GetClose(bars.Count - 2) + offset; renkoLow = bars.GetClose(bars.Count - 2) - offset * 2; } else { renkoHigh = bars.GetClose(bars.Count - 2) + offset * 2; renkoLow = bars.GetClose(bars.Count - 2) - offset; } } if (bars.Instrument.MasterInstrument.Compare(close, renkoHigh) >= 0) { if (bars.Instrument.MasterInstrument.Compare(bar.Open, renkoHigh - offset) != 0 || bars.Instrument.MasterInstrument.Compare(bar.High, Math.Max(renkoHigh - offset, renkoHigh)) != 0 || bars.Instrument.MasterInstrument.Compare(bar.Low, Math.Min(renkoHigh - offset, renkoHigh)) != 0) { bars.RemoveLastBar(isRealtime); // Note: bar is now just a local var and not in series! AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, renkoHigh), Math.Min(renkoHigh - offset, renkoHigh), renkoHigh, time, bar.Volume + volume, isRealtime); } else UpdateBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, renkoHigh), Math.Min(renkoHigh - offset, renkoHigh), renkoHigh, time, volume, isRealtime); renkoLow = renkoHigh - 2.0 * offset; renkoHigh = renkoHigh + offset; while (bars.Instrument.MasterInstrument.Compare(close, renkoHigh) >= 0) // add empty bars to fill gap { AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, renkoHigh), Math.Min(renkoHigh - offset, renkoHigh), renkoHigh, time, 1, isRealtime); renkoLow = renkoHigh - 2.0 * offset; renkoHigh = renkoHigh + offset; } // add final partial bar AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, close), Math.Min(renkoHigh - offset, close), close, time, 1, isRealtime); } else if (bars.Instrument.MasterInstrument.Compare(close, renkoLow) <= 0) { if (bars.Instrument.MasterInstrument.Compare(bar.Open, renkoLow + offset) != 0 || bars.Instrument.MasterInstrument.Compare(bar.High, Math.Max(renkoLow + offset, renkoLow)) != 0 || bars.Instrument.MasterInstrument.Compare(bar.Low, Math.Min(renkoLow + offset, renkoLow)) != 0) { bars.RemoveLastBar(isRealtime); // Note: bar is now just a local var and not in series! AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, time, bar.Volume + volume, isRealtime); } else UpdateBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, time, volume, isRealtime); renkoHigh = renkoLow + 2.0 * offset; renkoLow = renkoLow - offset; while (bars.Instrument.MasterInstrument.Compare(close, renkoLow) <= 0) // add empty bars to fill gap { AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, time, 1, isRealtime); renkoHigh = renkoLow + 2.0 * offset; renkoLow = renkoLow - offset; } // add final partial bar AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, close), Math.Min(renkoLow + offset, close), close, time, 1, isRealtime); } else // Note: open does not really change UpdateBar(bars, close, close, close, close, time, volume, isRealtime); bars.LastPrice = close; tmpCount = bars.Count; }
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 OnCalculate() { string strReversalTradeLong = "ReversalTradeLong" + ProcessingBarIndex; string strReversalTradeShort = "ReversalTradeShort" + ProcessingBarIndex; string strTradeResultLong; string strTradeResultShort; Color colorTextBox; // 1 umkehr fallend auf steigend //-1 umkehr steigend auf fallend if (IsReversalLongTrade() == true) { ReversalTradeStartTSLong = Bars[0].Time; //TargetBarTime = GetTargetBar(Bars[0].Time); TargetBarTime = GlobalUtilities.GetTargetBar(Bars, Bars[0].Time, TimeFrame, 1); OutSeries.Set(100); Reversal2NextBar.Set(100); } else if (IsReversalShortTrade() == true) { ReversalTradeStartTSShort = Bars[0].Time; //TargetBarTime = GetTargetBar(Bars[0].Time); TargetBarTime = GlobalUtilities.GetTargetBar(Bars, Bars[0].Time, TimeFrame, 1); OutSeries.Set(-100); } else { Reversal2NextBar.Set(0); } //TradingKerze ist fertig, Zeiteinheit ist abgelaufen if (Bars[0].Time == TargetBarTime) { ReversalTradeResult = (decimal)Bars.GetClose(ProcessingBarIndex) - (decimal)Bars.GetOpen(ProcessingBarIndex); TradeCounter += 1; if (ReversalTradeStartTSLong > DateTime.MinValue) { ReversalTradeResultTotalLong = ReversalTradeResultTotalLong + ReversalTradeResult; if (ReversalTradeResult < 0) { strTradeResultLong = "Fail " + ReversalTradeResult.ToString(); colorTextBox = colFail; TradeCounterLongFail += 1; } else { strTradeResultLong = "Win " + ReversalTradeResult.ToString(); colorTextBox = colWin; TradeCounterLongWin += 1; } AddChartText(strReversalTradeLong, true, strTradeResultLong, Time[1], Bars.GetHigh(ProcessingBarIndex) + (100 * TickSize), 9, Color.Black, new Font("Arial", 9), StringAlignment.Center, Color.Black, colorTextBox, 70); } else if (ReversalTradeStartTSShort > DateTime.MinValue) { ReversalTradeResultTotalShort = ReversalTradeResultTotalShort + ReversalTradeResult; if (ReversalTradeResult < 0) { strTradeResultShort = "Win " + ReversalTradeResult.ToString(); colorTextBox = colWin; TradeCounterShortWin += 1; } else { strTradeResultShort = "Fail " + ReversalTradeResult.ToString(); colorTextBox = colFail; TradeCounterShortFail += 1; } AddChartText(strReversalTradeShort, true, strTradeResultShort, Time[1], Bars.GetHigh(ProcessingBarIndex) - (100 * TickSize), 9, Color.Black, new Font("Arial", 9), StringAlignment.Center, Color.Black, colorTextBox, 70); } //Variablen Resetten ReversalTradeStartTSLong = DateTime.MinValue; ReversalTradeStartTSShort = DateTime.MinValue; } if (IsProcessingBarIndexLast) { // Print("LongWin: " + TradeCounterLongWin + " LongFail: " + TradeCounterLongFail + " ShortWin: " + TradeCounterShortWin + " ShortFail: " + TradeCounterShortFail); // Print(Instrument.Name + "Trades: " + TradeCounter + " LongPunkte: " + ReversalTradeResultTotalLong + " ShortPunkte: " + ReversalTradeResultTotalShort); } }
//protected override void OnBarUpdate() //{ // //TODO: Write your owner OnBarUpdate handling // //DrawArrowUp("Arrowup" + CurrentBar, true, Bars.GetTime(Count - 1), Bars.GetLow(CurrentBar) - 300 * TickSize, Color.Red); // //DrawArrowDown("Arrowdown" + CurrentBar, true, Bars.GetTime(Count - 1), Bars.GetHigh(CurrentBar) + 300 * TickSize, Color.Green); // //Occurred.Set(-1); // //Entry.Set(Close[0]); //} protected override void OnBarUpdate() { //MyGap.Set(Input[0]); if (Bars != null && Bars.Count > 0) // && TimeFrame.Periodicity == DatafeedHistoryPeriodicity.Minute // && TimeFrame.PeriodicityValue == 15) { } else { return; } if (Bars.BarsSinceSession == 0) { sessionprocessed = false; } //08.00, 08.15, 08.30, 08.45, 09.00 sind abgeschlossen -> es ist 09.15) // if(Bars.BarsSinceSession == 5) if (ToTime(Bars.GetTime(CurrentBar)) > 90000 && //größer 09.00 geht für 15M und 1Std (und 1Tag?) sessionprocessed == false) //Tag noch nicht verarbeitet { sessionprocessed = true; GapTradeLong = GapTradeShort = false; IBar GapOpenBar = Bars.Where(x => x.Time.Date == Bars[0].Time.Date).FirstOrDefault(); //liefert erster kerze des tages double GapOpen = GapOpenBar.Open; double LastDayClose = PriorDayOHLC().PriorClose[0]; double GapSize = GapOpen - LastDayClose; DateTime LastDayCloseDate = Bars.GetTime(Count - 7); DateTime LastPeriod = Time[1]; if (LastDayClose != null && Math.Abs(LastDayClose - GapOpen) > _PunkteGapMin && Math.Abs(LastDayClose - GapOpen) < _PunkteGapMax) { //Wenn Gap größer 50 und kleiner 100 existgap = true; //Gap markieren (08.00 - 09.15) string strMyRect = "MyRect" + Count; string strMyGapSize = "MyGapSize" + Count; if (LastDayClose - GapOpen < 0) //Long { //Long //DrawRectangle(strMyRect, true, LastDayCloseDate, LastDayClose, LastPeriod, HighestHighPrice(5)[0], _col_gap, _col_gap, 70); DrawText(strMyGapSize, true, Math.Round(GapSize, 1).ToString(), LastDayCloseDate, LastDayClose + 25, 9, Color.Black, new Font("Areal", 9), StringAlignment.Center, Color.Black, Color.Azure, 1); // if (LinReg(5)[0] > GapOpen) if (LinReg(Closes[0], 5)[0] > GapOpen) { //Chancenreicher SuccessTrade string strArrowUp = "ArrowUp" + Bars.GetTime(CurrentBar); DrawArrowUp(strArrowUp, true, Bars.GetTime(Count - 1), Bars.GetOpen(CurrentBar) - 300 * TickSize, Color.Green); GapTradeLong = true; Occurred.Set(1); Entry.Set(Bars.GetOpen(CurrentBar)); } } else { //Short //DrawRectangle(strMyRect, true, LastDayCloseDate, LastDayClose, LastPeriod, LowestLowPrice(5)[0], Color.Pink, Color.Pink, 70); DrawText(strMyGapSize, true, Math.Round(GapSize, 1).ToString(), LastDayCloseDate, LastDayClose - 25, 9, Color.Black, new Font("Areal", 9), StringAlignment.Center, Color.Black, Color.Azure, 1); if (LinReg(Closes[0], 5)[0] < GapOpen) { ////Chancenreicher SuccessTrade string strArrowDown = "ArrowDown" + Bars.GetTime(CurrentBar); DrawArrowDown(strArrowDown, true, Bars.GetTime(Count - 1), Bars.GetOpen(CurrentBar) + 300 * TickSize, Color.Red); GapTradeShort = true; Occurred.Set(-1); Entry.Set(Bars.GetOpen(CurrentBar)); } } if (GapTradeShort == true || GapTradeLong == true) { Print("------------------" + Time[5] + "------------------"); Print("LineReg: " + Math.Round(LinReg(5)[0]), 1); Print("Gap Open: " + GapOpen); } } else { existgap = false; } } //09.15. - 09.30 Kerze else if (Bars.BarsSinceSession == 6 && existgap == true) { //Auswertung decimal GapTradeResult; Color colorTextBox; GapTradeResult = (decimal)Bars.GetClose(CurrentBar - 1) - (decimal)Bars.GetOpen(CurrentBar - 1); if (GapTradeLong == true) { //Long GapTradeCounterLong += 1; GapTradeResultTotalLong = GapTradeResultTotalLong + GapTradeResult; string strGapeTradeLong = "GapTradeLong" + CurrentBar; string strTradeResultLong; if (GapTradeResult < 0) { Print("FAAAAAAAAAAAAAAAIIIIIIIIIIIIIILLLLLLLLLL"); GapTradeFailCounterLong += 1; strTradeResultLong = "Fail " + GapTradeResult.ToString(); colorTextBox = colFail; } else { GapTradeWinCounterLong += 1; strTradeResultLong = "Win " + GapTradeResult.ToString(); colorTextBox = colWin; } DrawText(strGapeTradeLong, true, strTradeResultLong, Time[1], Bars.GetHigh(CurrentBar - 1) + 10, 9, Color.Black, new Font("Areal", 9), StringAlignment.Center, Color.Black, colorTextBox, 70); } else if (GapTradeShort == true) { //Short GapTradeCounterShort += 1; GapTradeResultTotalShort = GapTradeResultTotalShort - GapTradeResult; string strGapeTradeShort = "GapTradeLong" + CurrentBar; string strTradeResultShort; if (GapTradeResult > 0) { Print("FAAAAAAAAAAAAAAAIIIIIIIIIIIIIILLLLLLLLLL"); GapTradeFailCounterShort += 1; strTradeResultShort = "Fail " + GapTradeResult.ToString(); colorTextBox = colFail; } else { GapTradeWinCounterShort += 1; strTradeResultShort = "Win " + GapTradeResult.ToString(); colorTextBox = colWin; } DrawText(strGapeTradeShort, true, strTradeResultShort, Time[1], Bars.GetLow(CurrentBar - 1) - 10, 9, Color.Black, new Font("Areal", 9), StringAlignment.Center, Color.Black, colorTextBox, 70); } Print("Gap Trade Result: " + GapTradeResult); } if (Count == Bars.Count - 1) { Print("Total Trades Long: " + GapTradeCounterLong); Print("Wins Long: " + GapTradeWinCounterLong); Print("Fails Long: " + GapTradeFailCounterLong); Print("Total Trades Short: " + GapTradeCounterShort); Print("Wins Short: " + GapTradeWinCounterShort); Print("Fails Short: " + GapTradeFailCounterShort); if (GapTradeCounterLong > 0) { Print("Avg Long: " + (GapTradeResultTotalLong / GapTradeCounterLong)); } if (GapTradeCounterShort > 0) { Print("Avg Short: " + (GapTradeResultTotalShort / GapTradeCounterShort)); } } }
/// <summary> /// </summary> /// <param name="bars"></param> /// <param name="open"></param> /// <param name="high"></param> /// <param name="low"></param> /// <param name="close"></param> /// <param name="time"></param> /// <param name="volume"></param> /// <param name="isRealtime"></param> public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime) { #region Building Bars from Base Period if (bars.Count != tmpCount) // reset cache when bars are trimmed if (bars.Count == 0) { tmpTime = Cbi.Globals.MinDate; tmpVolume = 0; tmpDayCount = 0; tmpTickCount = 0; } else { tmpTime = bars.GetTime(bars.Count - 1); tmpVolume = bars.GetVolume(bars.Count - 1); tmpTickCount = bars.TickCount; tmpDayCount = bars.DayCount; bars.LastPrice = anchorPrice = bars.GetClose(bars.Count - 1); } switch (bars.Period.BasePeriodType) { case PeriodType.Day: tmpTime = time.Date; if (isRealtime && time >= cacheSessionEnd) { tmpDayCount++; bars.Session.GetSessionDate(time, false, out tmpTime, out cacheSessionEnd); if (tmpTime < time.Date) tmpTime = time.Date; // make sure timestamps are ascending } if (!isRealtime && prevTimeD != tmpTime) tmpDayCount++; if ((!isRealtime && bars.Count > 0 && tmpTime == bars.TimeLastBar.Date) || (isRealtime && bars.Count > 0 && tmpTime <= bars.TimeLastBar.Date) || tmpDayCount < bars.Period.BasePeriodValue) endOfBar = false; else { prevTime = prevTimeD == Cbi.Globals.MinDate ? tmpTime : prevTimeD; prevTimeD = tmpTime; endOfBar = true; } break; case PeriodType.Minute: if (tmpTime == Cbi.Globals.MinDate) prevTime = tmpTime = TimeToBarTimeMinute(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue, isRealtime); if (!isRealtime && time <= tmpTime || isRealtime && time < tmpTime) endOfBar = false; else { prevTime = tmpTime; tmpTime = TimeToBarTimeMinute(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue, isRealtime); endOfBar = true; } break; case PeriodType.Volume: if (tmpTime == Cbi.Globals.MinDate) { tmpVolume = volume; endOfBar = tmpVolume >= bars.Period.BasePeriodValue; prevTime = tmpTime = time; if (endOfBar) tmpVolume = 0; break; } tmpVolume += volume; endOfBar = tmpVolume >= bars.Period.BasePeriodValue; if (endOfBar) { prevTime = tmpTime; tmpVolume = 0; tmpTime = time; } break; case PeriodType.Month: if (tmpTime == Cbi.Globals.MinDate) prevTime = tmpTime = TimeToBarTimeMonth(time, bars.Period.BasePeriodValue); if (time.Month <= tmpTime.Month && time.Year == tmpTime.Year || time.Year < tmpTime.Year) endOfBar = false; else { prevTime = tmpTime; endOfBar = true; tmpTime = TimeToBarTimeMonth(time, bars.Period.BasePeriodValue); } break; case PeriodType.Second: if (tmpTime == Cbi.Globals.MinDate) { prevTime = tmpTime = TimeToBarTimeSecond(bars, time, new DateTime(bars.Session.NextBeginTime.Year, bars.Session.NextBeginTime.Month, bars.Session.NextBeginTime.Day, bars.Session.NextBeginTime.Hour, bars.Session.NextBeginTime.Minute, 0), bars.Period.BasePeriodValue); } if (time <= tmpTime) endOfBar = false; else { prevTime = tmpTime; tmpTime = TimeToBarTimeSecond(bars, time, bars.Session.NextBeginTime, bars.Period.BasePeriodValue); endOfBar = true; } break; case PeriodType.Tick: if (tmpTime == Cbi.Globals.MinDate || bars.Period.BasePeriodValue == 1) { prevTime = tmpTime = time; tmpTickCount = bars.Period.BasePeriodValue == 1 ? 0 : 1; endOfBar = bars.Period.BasePeriodValue == 1; break; } if (tmpTickCount < bars.Period.BasePeriodValue) { tmpTime = time; endOfBar = false; tmpTickCount++; } else { prevTime = tmpTime; tmpTime = time; endOfBar = true; tmpTickCount = 1; } break; case PeriodType.Week: if (tmpTime == Cbi.Globals.MinDate) prevTime = tmpTime = TimeToBarTimeWeek(time.Date, tmpTime.Date, bars.Period.BasePeriodValue); if (time.Date <= tmpTime.Date) endOfBar = false; else { prevTime = tmpTime; endOfBar = true; tmpTime = TimeToBarTimeWeek(time.Date, tmpTime.Date, bars.Period.BasePeriodValue); } break; case PeriodType.Year: if (tmpTime == Cbi.Globals.MinDate) prevTime = tmpTime = TimeToBarTimeYear(time, bars.Period.Value); if (time.Year <= tmpTime.Year) endOfBar = false; else { prevTime = tmpTime; endOfBar = true; tmpTime = TimeToBarTimeYear(time, bars.Period.Value); } break; default: break; } #endregion #region P&F logic double tickSize = bars.Instrument.MasterInstrument.TickSize; boxSize = Math.Floor(10000000.0 * bars.Period.Value * tickSize) / 10000000.0; reversalSize = bars.Period.Value2 * boxSize; if (bars.Count == 0 || (IsIntraday && bars.IsNewSession(time, isRealtime))) { if (bars.Count > 0) { double lastOpen = bars.GetOpen(bars.Count - 1); double lastHigh = bars.GetHigh(bars.Count - 1); double lastLow = bars.GetLow(bars.Count - 1); double lastClose = bars.GetClose(bars.Count - 1); DateTime lastTime = bars.GetTime(bars.Count - 1); bars.LastPrice = anchorPrice = lastClose; if (bars.Count == tmpCount) CalculatePfBar(bars, lastOpen, lastHigh, lastLow, lastClose, prevTime, lastTime, isRealtime); } AddBar(bars, close, close, close, close, tmpTime, volume, isRealtime); anchorPrice = close; trend = Trend.Undetermined; prevTime = tmpTime; volumeCount = 0; bars.LastPrice = close; tmpCount = bars.Count; tmpHigh = high; tmpLow = low; return; } Bar bar = (Bar)bars.Get(bars.Count - 1); double c = bar.Close; double o = bar.Open; double h = bar.High; double l = bar.Low; DateTime t = bar.Time; if (endOfBar) { CalculatePfBar(bars, o, h, l, c, prevTime, t, isRealtime); volumeCount = volume; tmpHigh = high; tmpLow = low; } else { tmpHigh = (high > tmpHigh ? high : tmpHigh); tmpLow = (low < tmpLow ? low : tmpLow); volumeCount += volume; } bars.LastPrice = close; tmpCount = bars.Count; #endregion }