Peak-Valley Algorithm

Discussion in 'Automated Trading' started by frostengine, Jul 2, 2008.

  1. Does anyone know of an algorithm for finding all the peaks and valleys in a time series?
  2. MGJ


    Define peak.

    One possible definition among many is: For an OHLC time series of daily price data, day i is a "peak" if and only if both of these conditions hold:
    • High > High[i-1]
      [*]High > High[i+1]
    You may have something different in mind. You may want to use a Close-Only time series. You may want to extend the tippitty-tip-top criterion more than one day fore and aft.

    Define peak.
  3. To determine the highs and lows of a trend, you must first determine how much a move constitutes a trend classification. If the market moves 1 pt, do you consider it a trend? The lower this value, the more highs and lows you will get.

    Take the following scenario:

    The market starts at 1340.00, moves up to 1342.00, moves down to 1340.75, then up to 1345.00, then back down to 1341.00

    (the above movements are hypothetical and realistically, the market would never move so smoothly without tick fluctuations. I have simplified it for the sake of demonstration.)

    In the above scenario, if you consider a 1 pt move a trend, you would have the following high and low values:

    Low: 1340.00
    High: 1342.00
    Low: 1340.75
    High: 1345.00
    Low: 1341.00

    If you were to consider a trend as being at least a 3 pt move, then you would have the following:

    Low: 1340.00
    High: 1345.00
    Low: 1341.00

    What you want to consider a trend is your choice. The code below should get you started. It is written in C# for use in the NinjaTrader platform. Most programming languages have a similar syntax so it should carry over to whatever platform you are using fairly easily. I have read yours posts in the past Frost so I know that you are familiar with coding. If you want any clarification though, feel free to ask.


    // Detecting highs and lows of a trend
    // Variables
    double trend_high = 0; // Stores the value of the high (peak) of the trend
    double trend_low = 99999; // Stores the value for the low (valley) of the trend
    double trend_min_move = 2.00; // The minimum the market has to move to be considered a trend

    // Monitor price movement to determine trend highs and lows
    if(High[0] > trend_high
    && (High[0] - trend_low) >= trend_min_move)

    // A new trend high has been detected.
    trend_high = High[0];


    if(Low[0] < trend_low
    && trend_low <= (trend_high - trend_min_move)

    // A new trend low has been detected
    trend_low = Low[0];



    In the above code, I used 2 pts to define the minimum the market has to move to be considered a trend. This number was randomly chosen. Substitute it with what you find works. Also, note that the trend_high and trend_low variables each have a default value. I have done this so the code has a value to compare against to initially determine trend highs and lows. Furthermore, do not try to combine the two IF conditions in the code with an ELSE IF statement. Doing so will prevent the code from properly determining highs and lows if a trend high and low both occur in the same bar.

    btw.. I just wrote the above code right now and have never actually tested it. It should work though.
  4. we made suck a ''hi-lo detector'' as we call it using a very fast moving average and then you measure when the slope of said moving average makes a inflection point. inflection points are your highs and lows. the faster the ema, the more highs and lows you will get. we settled for a 3 period t3 moving average.
  5. would you mind showing maybe a three-five year daily plot of any instrument with highs and lows (found by this algorithm) identified ? Say, using a 5 % (rather use % relative to prior pt. than numerical pts) threshold for a trend definition here.

    I've done this type of work before (albeit different algorithms) and the results tended to run into subjectivity.
  6. Actually, I just looked through the code and there are some logic errors. Gimme like 20 mins, I'll have something working.
  7. ATLien


  8. K, the code below is actual tested code that will plot the values for the high and lows of a trend in NinjaTrader.

    Please this portion in the variable declaration area. It should only be called once, and NOT ON EVER TICK OR BAR!

    // Variables
    double trend_high = 0; // Stores the value of the high (peak) of the trend
    double trend_low = 99999; // Stores the value for the low (valley) of the trend
    double trend_min_move = 4.00; // The minimum the market has to move to be considered a trend
    double compare_high = 0; // High value to compare to when a new trend low is detected
    double compare_low = 0; // Low value to compare to when a new trend high is detected
    int variable_values_given = 0; // Whether or not values have been given to variables based on the chart

    Place the portion below in the area of your code so it is called on every new tick or bar (I recommend tick)

    // Set initial values
    if(variable_values_given == 0)

    // This is the first bar. Give values to the variables
    trend_high = Close[0];
    trend_low = Close[0];
    compare_high = Close[0];
    compare_low = Close[0];

    // Record that first bar values have been set
    variable_values_given = 1;


    // Monitor price movement for new highs and lows
    if(High[0] > compare_high
    && High[0] >= (trend_low + trend_min_move))

    // New trend high detected
    // Set variables accordingly
    trend_high = High[0];
    compare_high = High[0];
    compare_low = High[0];

    // Draw a dot to graphically point out the trend high
    DrawDot(Convert.ToString(ToTime(Time[0])) + Bars.TickCount, true, 0, High[0] + TickSize, Color.Blue);


    if(Low[0] < compare_low
    && Low[0] <= (trend_high - trend_min_move))

    // New trend low detected
    // Set variables accordingly
    trend_low = Low[0];
    compare_high = Low[0];
    compare_low = Low[0];

    // Draw a dot to graphically point out the trend low
    DrawDot(Convert.ToString(ToTime(Time[0])) + Bars.TickCount, true, 0, Low[0] - TickSize, Color.Yellow);



    The above code uses points to determine if a enough of a move has occured. If you want to use percentages do this...

    Set the trend_min_move variable in the variable declaration area to the percent you would like, like below:

    int trend_min_move = 5; // Trend min move is set to a 5% move.

    Then replace trend_min_move everywhere else in the code with the following:

    (Close[0] * (trend_min_move * 0.01))

    I did not test the percentage code, but I think it should work. I have also attached a screenshot showing what the code in action looks like. It plots a blue dot over new highs in a trend, and a yellow dot under new lows in a trend.

    This approach is for determining exacts highs and lows of a trend, with a trend being classified based on a specific movement in price. You can also use movements in moving averages, stochastics, and such to determine if enough of a move has occurred to be classified as a trend.

    Let me know if you run into any problems.
  9. Seems interesting. I suppose you could also filter it to only plot the last point (blue or yellow), between transitions between a yellow and blue marker;
    thus marking local min and max's within the minimum spread (resolution) you identified.

    Thanks for sharing. I'll try to play with it more if I get a chance.
  10. Please remember that the minimum spread I used was randomly chosen, and has no real value to it. A proper value should be derived from extensive research on factors such as volatility, period length (timeframe for most), volume, and so forth. You can even set the minimum value to change according to fluctuations in the factors I just pointed out.
    #10     Jul 3, 2008