protected virtual bool CheckAcrossFrames(List <Frame> acrossFrames, AboveBelowDMA trueFor)
        {
            foreach (Frame frame in acrossFrames)
            {
                IIndicator displaced3x3 = frame.Indicators.First(k => k.Type == IndicatorType.DisplacedMovingAverage && k.ParentOrdinal == 0);

                double acrossHeight;
                double barHeight = frame.Bar.highMid - frame.Bar.lowMid;

                if (trueFor == AboveBelowDMA.Above)
                {
                    acrossHeight = displaced3x3.Value.Value - frame.Bar.lowMid;
                }
                else
                {
                    acrossHeight = frame.Bar.highMid - displaced3x3.Value.Value;
                }

                if ((acrossHeight / barHeight) > _acrossFramesCoefficient)
                {
                    return(false);
                }
            }

            return(true);
        }
        /// <summary>
        /// Determines if a list of leaderSides are equal to a specified value.
        /// </summary>
        /// <param name="leaderSides">The list of AboveBelowDMA values to examine.</param>
        /// <param name="trueFor">The AboveBelowDMA side all leaderSides should equal.</param>
        /// <returns>True if all leader values equal the truefor value.
        ///          False all leader values do not equal the truefor value.</returns>
        protected virtual bool CheckLeaders(List <AboveBelowDMA> leaderSides, AboveBelowDMA trueFor)
        {
            bool result = false;

            result = leaderSides.TrueForAll(x => x == trueFor);

            return(result);
        }
Example #3
0
        /*
         *  upThrust
         *  traverse >= 10 bars
         *  >= 7 bars have low bid above the 3x3
         *  >= 5 consecutive bars must have low bid above the 3x3
         *  sequence may not start with > 3 bars with low bid below 3x3
         *  if (any of?) top 3 bars of sequence have low bid below 3x3 then lowest low bid of those below the 3x3 must be > .386 ask price
         *  thrust range must be >= (.06 x thrust ReactionPrice)
         *  MACD histogram value of all thrust frames must be > 0
         *
         *  downThrust
         *  traverse >= 10 bars
         *  >= 7 bars have low bid above the 3x3
         *  >= 5 consecutive bars must have low bid above the 3x3
         *  sequence may not start with > 3 bars with low bid below 3x3
         *  if (any of?) top 3 bars of sequence have low bid below 3x3 then lowest low bid of those below the 3x3 must be > .386 ask price
         *  thrust range must be >= (.06 x thrust ReactionPrice)
         *  MACD histogram value of all thrust frames must be > 0
         *  above or below the 3x3?
         */
        #endregion

        /// <summary>
        /// Searches the chart for a thrust pattern.
        /// </summary>
        /// <param name="chart">Chart object containing at least 20 frames</param>
        /// <returns>A tradeable thrust object, if found.</returns>
        protected override Thrust DetectThrust()
        {
            Thrust thrust = null;

            if (_chart.Frames.Count >= 20)
            {
                Frame frame;

                bool  upThrustFound = false, downThrustFound = false;
                short above3x3Count = 0, above3x3Links = 0, below3x3Count = 0, below3x3Links = 0, across3x3Count = 0;

                Func <short> sequentialAbove3x3Count = () => { return(above3x3Links > 0 ? (short)(above3x3Links + 1) : (short)0); };
                Func <short> sequentialBelow3x3Count = () => { return(below3x3Links > 0 ? (short)(below3x3Links + 1) : (short)0); };

                AboveBelowDMA        previousCandleSide = AboveBelowDMA.Unknown, currentCandleSide = AboveBelowDMA.Unknown;
                List <AboveBelowDMA> leaderSides = new List <AboveBelowDMA>();

                // only need to sniff 20 frames to find thrust
                // if not in 20 frames, whatever thrust exists has yielded to a consolidation period .. no good
                short loopCount = 0;
                while (loopCount < 20)
                {
                    loopCount++;
                    int i = _chart.Frames.Count - loopCount;
                    frame = _chart.Frames[i];

                    IPriceBar  candle       = frame.Bar;
                    IIndicator displaced3x3 = frame.Indicators.First(k => k.Type == IndicatorType.DisplacedMovingAverage && k.ParentOrdinal == 0);

                    if (candle.lowMid >= displaced3x3.Value)
                    {
                        above3x3Count++;

                        if (previousCandleSide == AboveBelowDMA.Above)
                        {
                            above3x3Links++;
                        }

                        currentCandleSide = previousCandleSide = AboveBelowDMA.Above;
                    }
                    else if (candle.highMid <= displaced3x3.Value)
                    {
                        below3x3Count++;

                        if (previousCandleSide == AboveBelowDMA.Below)
                        {
                            below3x3Links++;
                        }

                        currentCandleSide = previousCandleSide = AboveBelowDMA.Below;
                    }
                    else
                    {
                        across3x3Count++;
                        currentCandleSide = previousCandleSide = AboveBelowDMA.Across;
                    }

                    // save the first 3 bar sides
                    if (leaderSides.Count < 3)
                    {
                        leaderSides.Add(currentCandleSide);
                    }

                    // start thrust parsing once 10 bars have been examined
                    if (loopCount > 9)
                    {
                        upThrustFound = sequentialAbove3x3Count() >= 6 && sequentialBelow3x3Count() <= 3 &&
                                        CheckLeaders(leaderSides, AboveBelowDMA.Above) && !Displaced3x3HasDoubleDip(i, EPatternDirection.Up);

                        downThrustFound = sequentialBelow3x3Count() >= 6 && sequentialAbove3x3Count() <= 3 &&
                                          CheckLeaders(leaderSides, AboveBelowDMA.Below) && !Displaced3x3HasDoubleDip(i, EPatternDirection.Down);

                        if (upThrustFound || downThrustFound)
                        {
                            EPatternDirection direction     = upThrustFound ? EPatternDirection.Up : EPatternDirection.Down;
                            Frame             reactionFrame = FindReactionFrame(frame, i, direction);

                            if (reactionFrame != null)
                            {
                                int           checkAcrossIndex = GetCheckAcrossIndex(reactionFrame, direction);
                                AboveBelowDMA checkAcrossSide  = upThrustFound ? AboveBelowDMA.Above : AboveBelowDMA.Below;

                                if (CheckAcrossFrames(checkAcrossIndex, checkAcrossSide))
                                {
                                    thrust = BuildThrust(reactionFrame, direction);
                                }
                            }

                            break;
                        }
                    }
                }
            }

            return(thrust);
        }
Example #4
0
        /*
         *  upThrust
         *  traverse >= 10 bars
         *  >= 7 bars have low bid above the 3x3
         *  >= 5 consecutive bars must have low bid above the 3x3
         *  sequence may not start with > 3 bars with low bid below 3x3
         *  if (any of?) top 3 bars of sequence have low bid below 3x3 then lowest low bid of those below the 3x3 must be > .386 ask price
         *  thrust range must be >= (.06 x thrust ReactionPrice)
         *  MACD histogram value of all thrust frames must be > 0
         *
         *  downThrust
         *  traverse >= 10 bars
         *  >= 7 bars have low bid above the 3x3
         *  >= 5 consecutive bars must have low bid above the 3x3
         *  sequence may not start with > 3 bars with low bid below 3x3
         *  if (any of?) top 3 bars of sequence have low bid below 3x3 then lowest low bid of those below the 3x3 must be > .386 ask price
         *  thrust range must be >= (.06 x thrust ReactionPrice)
         *  MACD histogram value of all thrust frames must be > 0
         *  above or below the 3x3?
         */
        #endregion

        /// <summary>
        /// Searches the chart for a thrust pattern.
        /// </summary>
        /// <param name="chart">Chart object containing at least 20 frames</param>
        /// <returns>A tradeable thrust object, if found.</returns>
        protected override Thrust DetectThrust()
        {
            Thrust thrust = null;

            if (_chart.Frames.Count >= 20)
            {
                Frame frame;

                bool  upThrustFound = false, downThrustFound = false;
                short above3x3Count = 0, below3x3Count = 0, across3x3Count = 0;

                AboveBelowDMA        currentCandleSide = AboveBelowDMA.Unknown;
                List <AboveBelowDMA> leaderSides = new List <AboveBelowDMA>();
                List <Frame>         acrossFrames = new List <Frame>();

                // only need to sniff 20 frames to find thrust
                // if not in 20 frames, whatever thrust exists has yielded to a consolidation period .. no good
                for (int loopCount = 1; true; loopCount++)
                {
                    int i = _chart.Frames.Count - loopCount;
                    frame = _chart.Frames[i];

                    IPriceBar  candle       = frame.Bar;
                    IIndicator displaced3x3 = frame.Indicators.First(k => k.Type == IndicatorType.DisplacedMovingAverage && k.ParentOrdinal == 0);

                    if (candle.lowMid >= displaced3x3.Value)
                    {
                        above3x3Count++;
                        currentCandleSide = AboveBelowDMA.Above;
                    }
                    else if (candle.highMid <= displaced3x3.Value)
                    {
                        below3x3Count++;
                        currentCandleSide = AboveBelowDMA.Below;
                    }
                    else
                    {
                        across3x3Count++;
                        currentCandleSide = AboveBelowDMA.Across;
                        acrossFrames.Add(frame);
                    }

                    // save the first 3 bar sides
                    if (leaderSides.Count < 3)
                    {
                        leaderSides.Add(currentCandleSide);
                    }

                    // start thrust parsing once 10 bars have been examined
                    if (loopCount == 7)
                    {
                        upThrustFound = above3x3Count >= 5 && below3x3Count == 0 && CheckLeaders(leaderSides, AboveBelowDMA.Above) && CheckAcrossFrames(acrossFrames, AboveBelowDMA.Above);

                        downThrustFound = below3x3Count >= 5 && above3x3Count == 0 && CheckLeaders(leaderSides, AboveBelowDMA.Below) && CheckAcrossFrames(acrossFrames, AboveBelowDMA.Below);

                        if (upThrustFound || downThrustFound)
                        {
                            EPatternDirection direction     = upThrustFound ? EPatternDirection.Up : EPatternDirection.Down;
                            Frame             reactionFrame = FindReactionFrame(frame, i, direction);

                            if (reactionFrame != null)
                            {
                                int           checkAcrossIndex = GetCheckAcrossIndex(reactionFrame, direction);
                                AboveBelowDMA checkAcrossSide  = upThrustFound ? AboveBelowDMA.Above : AboveBelowDMA.Below;

                                if (CheckAcrossFrames(checkAcrossIndex, checkAcrossSide))
                                {
                                    thrust = BuildThrust(reactionFrame, direction);
                                }
                            }
                        }

                        break;
                    }
                }
            }

            return(thrust);
        }
        /// <summary>
        /// Checks each frame price bar after the startIndex frame price bar to discover those that cross the 3x3.
        /// If a bar crosses the 3x3, no more than 0.382*[bar length] may be across the 3x3.
        /// </summary>
        /// <param name="reactionIndex"></param>
        /// <param name="trueFor"></param>
        /// <returns></returns>
        protected virtual bool CheckAcrossFrames(int startIndex, AboveBelowDMA trueFor)
        {
            IEnumerable <Frame> afterReactionFrames = _chart.Frames.Skip(startIndex + 1);

            return(CheckAcrossFrames(afterReactionFrames.ToList(), trueFor));
        }