public Dictionary <BarrierDirection, decimal> GetSpacingAroundTarget(AggregateLines Lines, int BarNumber, decimal TargetValue) { Dictionary <BarrierDirection, decimal> directionSpacing = new Dictionary <BarrierDirection, decimal>(); Dictionary <BarrierDirection, List <IAggregateLine> > linesOfSameDirection = GetLinesOfSameDirection(Lines); foreach (BarrierDirection key in linesOfSameDirection.Keys) { decimal?previousLineValue = null; decimal?spacing = null; bool isTargetReached = false; foreach (IAggregateLine line in linesOfSameDirection[key].OrderBy(b => b.GetValueAt(BarNumber))) { decimal lineCurrentValue = line.GetValueAt(BarNumber); if (previousLineValue == null) { if (lineCurrentValue > TargetValue) { isTargetReached = true; break; } previousLineValue = lineCurrentValue; } else { spacing = lineCurrentValue - previousLineValue; if (lineCurrentValue > TargetValue) { isTargetReached = true; break; } previousLineValue = lineCurrentValue; } } if ((spacing != null) && isTargetReached) { directionSpacing.Add(key, spacing ?? 0.0M); } } return(directionSpacing); }
private Dictionary <BarrierDirection, List <IAggregateLine> > GetLinesOfSameDirection(AggregateLines Lines) { Dictionary <BarrierDirection, List <IAggregateLine> > linesOfSameDirection = new Dictionary <BarrierDirection, List <IAggregateLine> >(); foreach (IAggregateLine line in Lines.Lines) { if (!linesOfSameDirection.ContainsKey(line.BarrierDirection)) { linesOfSameDirection.Add(line.BarrierDirection, new List <IAggregateLine>()); } linesOfSameDirection[line.BarrierDirection].Add(line); } return(linesOfSameDirection); }
/// <summary> /// Sets IsCongested and CongestedBoundary on the passed lines /// </summary> /// <param name="Lines"></param> /// <param name="BarNumber"></param> public void GetCongestion(ref AggregateLines Lines, int BarNumber) { Dictionary <BarrierDirection, List <IAggregateLine> > linesOfSameDirection = GetLinesOfSameDirection(Lines); foreach (BarrierDirection key in linesOfSameDirection.Keys) { decimal currentLimit = Decimal.MinValue; IAggregateLine previousLine = null; bool isCongested = false; bool isPreviousSetToLower = false; bool isPreviousSetToUpper = false; foreach (IAggregateLine line in linesOfSameDirection[key].OrderBy(b => b.GetValueAt(BarNumber))) { isPreviousSetToLower = false; isPreviousSetToUpper = false; decimal lineCurrentValue = line.GetValueAt(BarNumber); //if ((lineCurrentValue - line.ProximateDistance) <= currentLimit) if ((lineCurrentValue - line.CongestionDistance) <= currentLimit) { if (!isCongested) { isPreviousSetToLower = true; } isCongested = true; } else { if (isCongested) { isPreviousSetToUpper = true; isCongested = false; } } line.IsCongested = isCongested; line.CongestedBoundary = CongestionBoundary.NotSet; if (isPreviousSetToLower) { previousLine.CongestedBoundary = CongestionBoundary.Lower; previousLine.IsCongested = true; } if (isPreviousSetToUpper) { previousLine.CongestedBoundary = CongestionBoundary.Upper; previousLine.IsCongested = true; } //currentLimit = lineCurrentValue + line.ProximateDistance; currentLimit = lineCurrentValue + line.CongestionDistance; previousLine = line; } // if the last line was congested then it becomes a boundary if (isCongested) { previousLine.CongestedBoundary = CongestionBoundary.Upper; previousLine.IsCongested = true; } } }
public override void Get(ref object Prototype, IIndicatorValues Ind) { int atrPeriod = (int)this.IndicatorParameters.List[0]; decimal atrMultiple = (decimal)this.IndicatorParameters.List[1]; decimal proximityFraction = (decimal)this.IndicatorParameters.List[2]; List <IAggregateLine> linesToAdd = new List <IAggregateLine>(); decimal atr = Ind.ATR(atrPeriod)[0].Value; //================== // The ATR multiple is likely to increase the range of the lines by twice its value (TODO: a power law of sorts may work better) decimal approxSpacing = atr * (atrMultiple * 2.0M); //================== decimal doubleZeroIncrement = GetIncrement(approxSpacing); decimal proximateDistance = doubleZeroIncrement * proximityFraction; // TODO: need to deal with congestion differently as the proximity distance will now scale with the distance between lines //decimal congestionDistance = (doubleZeroIncrement * proximityFraction) * CONGESTION_FACTOR; decimal congestionDistance = 0.0M; if (doubleZeroIncrement > 0.0M) { decimal min = Ind.Bar[0].Close - (doubleZeroIncrement * MAX_LEVELS_ABOVEANDBELOW); decimal max = Ind.Bar[0].Close + (doubleZeroIncrement * MAX_LEVELS_ABOVEANDBELOW); decimal value = 0.0M; while (value < min) { value += doubleZeroIncrement; } for (; value <= max; value += doubleZeroIncrement) { linesToAdd.Add(new PriceLevel( Ind.Bar.CurrentBar, value, true, 0, this.FailureDistanceMultiple)); } } base.CleanLines(ref Prototype, Ind); foreach (IAggregateLine line in linesToAdd) { (Prototype as AggregateLines).Lines.Add(line); } // update thresholds and proximate distance / no need to update vertical threshold for double zeros foreach (IAggregateLine line in (Prototype as AggregateLines).Lines) { line.ProximateDistance = proximateDistance; line.CongestionDistance = congestionDistance; } // get congestion // TODO: does this work as expected AggregateLines lines = (Prototype as AggregateLines); GetCongestion(ref lines, Ind.Bar[0].Number); Prototype = lines; }