/// <summary> /// Calculate Open Range with all IBar and current IBar /// </summary> /// <param name="currentbar"></param> /// <returns></returns> public ORB_Result calculate(IBars bars, IBar currentbar) { //todo check if all data should be return via Result Object //todo check if it allowed that we are going two times through the limit (two buys per day, could this happen?) ORB_Result resultvalue = new ORB_Result(); //reset session day data this.LongBreakout = null; this.ShortBreakout = null; this.LongTargetReached = null; this.ShortTargetReached = null; //draw the open range resultvalue.Start = this.getOpenRangeStart(bars, currentbar.Time); resultvalue.End = this.getOpenRangeEnd(resultvalue.Start); //Select all data and find high & low. IEnumerable <IBar> list = bars.Where(x => x.Time >= resultvalue.Start).Where(x => x.Time <= resultvalue.End); //Check if there is data available if (list == null || list.IsEmpty()) { return(resultvalue); } //Check if data for open range is valid. //we need to ignore the first day which is normally invalid. if (list.First().Time != resultvalue.Start) { resultvalue.IsORBValid = false; } else { resultvalue.IsORBValid = true; } //Calculate range this.RangeLow = list.Where(x => x.Low == list.Min(y => y.Low)).LastOrDefault().Low; this.RangeHigh = list.Where(x => x.High == list.Max(y => y.High)).LastOrDefault().High; //Calculate targets this.TargetLong = this.RangeHigh + this.RangeHeight; this.TargetShort = this.RangeLow - this.RangeHeight; //tolreanz double toleranz = 0; // this.RangeHeight / 5; //load the data after the open range list = bars.Where(x => x.Time >= resultvalue.End).Where(x => x.Time <= this.getEndOfTradingDay(bars, resultvalue.Start)); //find the first breakout to the long side this.LongBreakout = list.Where(x => x.Close > this.RangeHigh + toleranz).FirstOrDefault(); //find the first breakout to the short side this.ShortBreakout = list.Where(x => x.Close < this.RangeLow - toleranz).FirstOrDefault(); //find the first target to the long side this.LongTargetReached = list.Where(x => x.Close > this.TargetLong).FirstOrDefault(); //find the first target to the short side this.ShortTargetReached = list.Where(x => x.Close < this.TargetShort).FirstOrDefault(); //Everything was fine resultvalue.IsCompleted = true; return(resultvalue); }
protected override void OnBarUpdate() { if (this.DatafeedPeriodicityIsValid(Bars)) { //new day session is beginning so we need to calculate the open range breakout //if we are calculation "older" trading days the whole day will be calculated because to enhance performance. if (this.CurrentdayOfUpdate.Date < Bars[0].Time.Date) { ORB_Result resultvalue = calculate(this.Bars, this.Bars[0]); //Draw if the calculate method was processed till the end if (resultvalue.IsCompleted) { //Set Color for open range Color openrangecolorvalidornot = this.Color_ORB; if (!resultvalue.IsORBValid) { openrangecolorvalidornot = this.Color_ORB_invalid; } //Draw the Open Range DrawRectangle("ORBRect" + resultvalue.StartDate.Ticks, true, resultvalue.Start, this.RangeLow, resultvalue.End, this.RangeHigh, openrangecolorvalidornot, openrangecolorvalidornot, this.Opacity); DrawText("ORBRangeString" + resultvalue.StartDate.Ticks, true, Math.Round((this.RangeHeight), 2).ToString(), resultvalue.Start, this.RangeHigh, 9, Color.Black, new Font("Arial", 9), StringAlignment.Center, Color.Gray, openrangecolorvalidornot, this.Opacity); //if we are live on the trading day if (this.Bars.Last().Time.Date == resultvalue.StartDate) { DrawHorizontalLine("LowLine" + resultvalue.StartDate.Ticks, true, this.RangeLow, openrangecolorvalidornot, this.CurrentSessionLineStyle, this.CurrentSessionLineWidth); DrawHorizontalLine("HighLine" + resultvalue.StartDate.Ticks, true, this.RangeHigh, openrangecolorvalidornot, this.CurrentSessionLineStyle, this.CurrentSessionLineWidth); } //Draw the target areas DrawRectangle("TargetAreaLong" + resultvalue.StartDate.Ticks, true, this.getOpenRangeEnd(this.getOpenRangeStart(this.Bars, resultvalue.StartDate)), this.RangeHigh, this.getEndOfTradingDay(this.Bars, resultvalue.StartDate), this.TargetLong, this.Color_TargetAreaLong, this.Color_TargetAreaLong, this.Opacity); DrawRectangle("TargetAreaShort" + resultvalue.StartDate.Ticks, true, this.getOpenRangeEnd(this.getOpenRangeStart(this.Bars, resultvalue.StartDate)), this.RangeLow, this.getEndOfTradingDay(this.Bars, resultvalue.StartDate), this.TargetShort, this.Color_TargetAreaShort, this.Color_TargetAreaShort, this.Opacity); } } //Set the indicator value on each bar update, if the breakout is on the current bar if (this.LongBreakout != null && this.LongBreakout.Time == Bars[0].Time) { BarColor = Color.Turquoise; Value.Set(1); DrawArrowUp("ArrowLong" + Bars[0].Time.Date.Ticks, true, this.LongBreakout.Time, this.LongBreakout.Low, Color.Green); } else if (this.ShortBreakout != null && this.ShortBreakout.Time == Bars[0].Time) { BarColor = Color.Purple; Value.Set(-1); DrawArrowDown("ArrowShort" + Bars[0].Time.Date.Ticks, true, this.ShortBreakout.Time, this.ShortBreakout.High, Color.Red); } else { Value.Set(0); } //todo statistic for timeout //todo statistic for stops //Draw the Long Target if this is necessary if (this.LongTargetReached != null) { DrawArrowDown("ArrowTargetLong" + Bars[0].Time.Date.Ticks, true, this.LongTargetReached.Time, this.LongTargetReached.High, Color.Red); //todo add statistic data //this._StatisticContainer.Add(); } //Draw the Short Target if this is necessary if (this.ShortTargetReached != null) { DrawArrowUp("ArrowTargetShort" + Bars[0].Time.Date.Ticks, true, this.ShortTargetReached.Time, this.ShortTargetReached.Low, Color.Green); //todo add statistic data //this._StatisticContainer.Add(); } //Set the color PlotColors[0][0] = this.Plot1Color; Plots[0].PenStyle = this.Dash0Style; Plots[0].Pen.Width = this.Plot0Width; //When finished set the last day variable //If we are online during the day session we do not set this variable so we are redrawing and recalculating the current session again and again if (GlobalUtilities.IsCurrentBarLastDayInBars(this.Bars, this.Bars[0])) { //the last session has started (current trading session, last day in Bars object, and so on) } else { this.CurrentdayOfUpdate = this.Bars[0].Time.Date; } } else { //Data feed perodicity is not valid, print info in chart panel if (IsCurrentBarLast) { DrawTextFixed("AlertText", Const.DefaultStringDatafeedPeriodicity, TextPosition.Center, Color.Red, new Font("Arial", 30), Color.Red, Color.Red, 20); } } }