Identifying Double Tops and Double Bottoms in Trading Charts

17 Dec 2020
0 comment
0 attachment

This ProBuilder script is designed to identify and visualize double top and double bottom patterns in trading charts, which are common technical analysis patterns used to predict reversals in market trends. The code dynamically adjusts to user-defined parameters for pattern recognition and visualization.

// Rainer-Franz Wirth Rainer (RFW) @ prorealcode.com
//***************************************************************************************************************************************
Defparam Drawonlastbaronly = True
DH = 0
DL = 0
//***************************************************************************************************************************************
//// Variables ////
//*****************
StartPeriod = Max(0,StartPeriod) // StartPeriod
SearchPeriod = Max(10,SearchPeriod) // LookBack Search-Periods, min.10
MaxDistance = Max(0,MaxDistance) // Allowed Distance Highs/Lows Double/Triple - 1 = 0.001%, 2 = 0.002% etc...
MinBarDistance = Max(1,MinBarDistance) // Min BarDistance Candle Highs/Lows
DisplayMod = Max(-1,DisplayMod) // -1 Check - 0 HLine - 1 HLine+Points - 2 HLine+Points+VLine - 3 All
ColourMod = Max(1,ColourMod) // 1 Green/Red - 2 Blue/Orange - 3 Red/Green - 4 Orange/Blue
//***************************************************************************************************************************************
//// Colours ////
//***************************************************************************************************************************************
// ColourMod 1: High Green, Low Red
// ColourMod 2: High Red, Low Green
// ColourMod 3: High Blue, Low Orange
// ColourMod 4: High Orange, Low Blue
//************************************
If ColourMod = 1 Then // High Green
    RCH1 = 0
    GCH1 = 255
    BCH1 = 0
    // Low Red
    RCL1 = 255
    GCL1 = 0
    BCL1 = 0
ElsIf ColourMod = 2 Then // High Red
    RCH1 = 255
    GCH1 = 0
    BCH1 = 0
    // Low Green
    RCL1 = 0
    GCL1 = 255
    BCL1 = 0
ElsIf ColourMod = 3 Then // High Blue
    RCH1 = 0
    GCH1 = 150
    BCH1 = 255
    // Low Orange
    RCL1 = 255
    GCL1 = 100
    BCL1 = 0
ElsIf ColourMod = 4 Then // High Orange
    RCH1 = 255
    GCH1 = 100
    BCH1 = 0
    // Low Blue
    RCL1 = 0
    GCL1 = 150
    BCL1 = 255
Endif
//***************************************************************************************************************************************
If IsLastBarupdate Then
    MaxBarindex = BarIndex
//********************* 
//// SearchPeriods ////
//********************
    SP0 = StartPeriod
    SPS = Min(MaxBarindex-1,(SearchPeriod-SP0-1))
//***********************************************
//// Check/Visualize Search Periods-Sections ////
//***********************************************
    If (DisplayMod = -1) Or (DisplayMod > 2) Then
        DRAWVLINE(BarIndex-SP0)Coloured(0,0,255)
        DRAWVLINE(BarIndex-SPS)Coloured(0,0,255)
    Endif
//***************************************************************************************************************************************
//************ 1. High
    HDT1 = Highest[SPS](High[SP0])
    For HDT1x = SP0 To SPS Do
        If High[HDT1x] = HDT1 Then
            HDT1 = High[HDT1x]
            HDT1B = BarIndex[HDT1x]
            Break
        EndIf
    Next
    HDTDUP = (HDT1*(1+(MaxDistance/100000)))
    HDTDDO = (HDT1*(1-(MaxDistance/100000)))
    If (DisplayMod = -1) Or (DisplayMod > 2) Then
        DRAWHLINE(HDTDDO)Coloured(255,0,0)
        DRAWHLINE(HDTDUP)Coloured(0,255,0)
        DRAWPOINT(HDT1B,HDT1,2)Coloured(RCH1,GCH1,BCH1)Bordercolor(RCH1,GCH1,BCH1)
    EndIf
//************ 2. High
    For HDT2x = SP0 To SPS Do
        If ((High[HDT2x] >= HDTDDO) And (High[HDT2x] =< HDTDUP)) And ((Abs(HDT1B-(BarIndex[HDT2x]))) >= MinBarDistance) Then
            HDT2 = High[HDT2x]
            HDT2B = BarIndex[HDT2x]
            DH = 2 // Double-Top
            If (DisplayMod = -1) Or (DisplayMod > 2) Then
                DRAWPOINT(HDT2B,HDT2,2)Coloured(RCH1,GCH1,BCH1)Bordercolor(RCH1,GCH1,BCH1)
            EndIf
            Break
        EndIf
    Next
//************ 3. High
    For HDT3x = SP0 To SPS Do
        If (High[HDT3x] >= HDTDDO) And (High[HDT3x] =< HDTDUP) And ((Abs(HDT2B-(BarIndex[HDT3x]))) >= MinBarDistance) And ((Abs(HDT1B-(BarIndex[HDT3x]))) >= MinBarDistance) Then
            HDT3 = High[HDT3x]
            HDT3B = BarIndex[HDT3x]
            DH = 3 // Triple-Top
            If (DisplayMod = -1) Or (DisplayMod > 2) Then
                DRAWPOINT(HDT3B,HDT3,2)Coloured(RCH1,GCH1,BCH1)Bordercolor(RCH1,GCH1,BCH1)
            EndIf
            Break
        EndIf
    Next
//***************************************************************************************************************************************3.
    If (DH = 2) Then
        DRAWHLINE(HDT1)Coloured(RCH1,GCH1,BCH1)Style(Line,2)
        If (DisplayMod > 0) Then // Line-Horizontal+Point
            DRAWPOINT(HDT1B,HDT1,2)Coloured(RCH1,GCH1,BCH1)Bordercolor(RCH1,GCH1,BCH1)
            DRAWPOINT(HDT2B,HDT2,2)Coloured(RCH1,GCH1,BCH1)Bordercolor(RCH1,GCH1,BCH1)
        EndIf
        If (DisplayMod > 1) Then // Line-Horizontal+Point+Line-Vertical
            DRAWPOINT(HDT1B,HDT1,2)Coloured(RCH1,GCH1,BCH1)Bordercolor(RCH1,GCH1,BCH1)
            DRAWPOINT(HDT2B,HDT2,2)Coloured(RCH1,GCH1,BCH1)Bordercolor(RCH1,GCH1,BCH1)
            DRAWVLINE(HDT1B)Coloured(RCH1,GCH1,BCH1)
            DRAWVLINE(HDT2B)Coloured(RCH1,GCH1,BCH1)
        Endif
    EndIf
    If (DH = 3) Then
        DRAWHLINE(HDT1)Coloured(RCH1,GCH1,BCH1)Style(Line,2)
        If (DisplayMod > 0) Then // Line-Horizontal+Point
            DRAWPOINT(HDT1B,HDT1,2)Coloured(RCH1,GCH1,BCH1)Bordercolor(RCH1,GCH1,BCH1)
            DRAWPOINT(HDT2B,HDT2,2)Coloured(RCH1,GCH1,BCH1)Bordercolor(RCH1,GCH1,BCH1)
            DRAWPOINT(HDT3B,HDT3,2)Coloured(RCH1,GCH1,BCH1)Bordercolor(RCH1,GCH1,BCH1)
        EndIf
        If (DisplayMod > 1) Then // Line-Horizontal+Point+Line-Vertical
            DRAWPOINT(HDT1B,HDT1,2)Coloured(RCH1,GCH1,BCH1)Bordercolor(RCH1,GCH1,BCH1)
            DRAWPOINT(HDT2B,HDT2,2)Coloured(RCH1,GCH1,BCH1)Bordercolor(RCH1,GCH1,BCH1)
            DRAWPOINT(HDT3B,HDT3,2)Coloured(RCH1,GCH1,BCH1)Bordercolor(RCH1,GCH1,BCH1)
            DRAWVLINE(HDT1B)Coloured(RCH1,GCH1,BCH1)
            DRAWVLINE(HDT2B)Coloured(RCH1,GCH1,BCH1)
            DRAWVLINE(HDT3B)Coloured(RCH1,GCH1,BCH1)
        EndIf
    Endif
//***************************************************************************************************************************************3.
//***************************************************************************************************************************************3.
//************ 1. Low
    LDT1 = Lowest[SPS](Low[SP0])
    For LDT1x = SP0 To SPS Do
        If Low[LDT1x] = LDT1 Then
            LDT1 = Low[LDT1x]
            LDT1B = BarIndex[LDT1x]
            Break
        EndIf
    Next
    LDTDUP = (LDT1*(1+(MaxDistance/100000)))
    LDTDDO = (LDT1*(1-(MaxDistance/100000)))
    If (DisplayMod = -1) Or (DisplayMod > 2) Then
        DRAWHLINE(LDTDDO)Coloured(255,0,0)
        DRAWHLINE(LDTDUP)Coloured(0,255,0)
        DRAWPOINT(LDT1B,LDT1,2)Coloured(RCL1,GCL1,BCL1)Bordercolor(RCL1,GCL1,BCL1)
    EndIf
//************ 2. Low
    For LDT2x = SP0 To SPS Do
        If ((Low[LDT2x] >= LDTDDO) And (Low[LDT2x] =< LDTDUP)) And ((Abs(LDT1B-(BarIndex[LDT2x]))) >= MinBarDistance) Then
            LDT2 = Low[LDT2x]
            LDT2B = BarIndex[LDT2x]
            DL = 2 // Double-Bottom
            If (DisplayMod = -1) Or (DisplayMod > 2) Then
                DRAWPOINT(LDT2B,LDT2,2)Coloured(RCL1,GCL1,BCL1)Bordercolor(RCL1,GCL1,BCL1)
            EndIf
            Break
        EndIf
    Next
//************ 3. Low
    For LDT3x = SP0 To SPS Do
        If (Low[LDT3x] >= LDTDDO) And (Low[LDT3x] =< LDTDUP) And ((Abs(LDT2B-(BarIndex[LDT3x]))) >= MinBarDistance) And ((Abs(LDT1B-(BarIndex[LDT3x]))) >= MinBarDistance) Then
            LDT3 = Low[LDT3x]
            LDT3B = BarIndex[LDT3x]
            DL = 3 // Triple-Bottom
            If (DisplayMod = -1) Or (DisplayMod > 2) Then
                DRAWPOINT(LDT3B,LDT3,2)Coloured(RCL1,GCL1,BCL1)Bordercolor(RCL1,GCL1,BCL1)
            EndIf
            Break
        EndIf
    Next
//***************************************************************************************************************************************3.
    If (DL = 2) Then
        DRAWHLINE(LDT1)Coloured(RCL1,GCL1,BCL1)Style(Line,2)
        If (DisplayMod > 0) Then // Line-Horizontal+Point
            DRAWPOINT(LDT1B,LDT1,2)Coloured(RCL1,GCL1,BCL1)Bordercolor(RCL1,GCL1,BCL1)
            DRAWPOINT(LDT2B,LDT2,2)Coloured(RCL1,GCL1,BCL1)Bordercolor(RCL1,GCL1,BCL1)
        EndIf
        If (DisplayMod > 1) Then // Line-Horizontal+Point+Line-Vertical
            DRAWPOINT(LDT1B,LDT1,2)Coloured(RCL1,GCL1,BCL1)Bordercolor(RCL1,GCL1,BCL1)
            DRAWPOINT(LDT2B,LDT2,2)Coloured(RCL1,GCL1,BCL1)Bordercolor(RCL1,GCL1,BCL1)
            DRAWVLINE(LDT1B)Coloured(RCL1,GCL1,BCL1)
            DRAWVLINE(LDT2B)Coloured(RCL1,GCL1,BCL1)
        Endif
    EndIf
    If (DL = 3) Then
        DRAWHLINE(LDT1)Coloured(RCL1,GCL1,BCL1)Style(Line,2)
        If (DisplayMod > 0) Then // Line-Horizontal+Point
            DRAWPOINT(LDT1B,LDT1,2)Coloured(RCL1,GCL1,BCL1)Bordercolor(RCL1,GCL1,BCL1)
            DRAWPOINT(LDT2B,LDT2,2)Coloured(RCL1,GCL1,BCL1)Bordercolor(RCL1,GCL1,BCL1)
            DRAWPOINT(LDT3B,LDT3,2)Coloured(RCL1,GCL1,BCL1)Bordercolor(RCL1,GCL1,BCL1)
        EndIf
        If (DisplayMod > 1) Then // Line-Horizontal+Point+Line-Vertical
            DRAWPOINT(LDT1B,LDT1,2)Coloured(RCL1,GCL1,BCL1)Bordercolor(RCL1,GCL1,BCL1)
            DRAWPOINT(LDT2B,LDT2,2)Coloured(RCL1,GCL1,BCL1)Bordercolor(RCL1,GCL1,BCL1)
            DRAWPOINT(LDT3B,LDT3,2)Coloured(RCL1,GCL1,BCL1)Bordercolor(RCL1,GCL1,BCL1)
            DRAWVLINE(LDT1B)Coloured(RCL1,GCL1,BCL1)
            DRAWVLINE(LDT2B)Coloured(RCL1,GCL1,BCL1)
            DRAWVLINE(LDT3B)Coloured(RCL1,GCL1,BCL1)
        EndIf
    Endif
//***************************************************************************************************************************************3.
EndIf // IsLastBarupdate
//***************************************************************************************************************************************
Return

Explanation of the Code:

  • The script starts by setting parameters such as the search period, the minimum distance between bars, and the maximum allowed distance for highs and lows to be considered part of a double or triple top/bottom.
  • It defines color schemes based on the user’s choice to visually differentiate between high and low points.
  • The main logic checks for double and triple tops and bottoms by comparing the high and low values within the defined search period and visualizes these patterns on the chart.
  • Visual elements like horizontal and vertical lines, and points are drawn on the chart to mark these patterns clearly.

This script is a practical tool for traders who use technical analysis to make informed decisions based on identified patterns in price charts.

Related Post

Check out this related content for more information:

https://www.prorealcode.com/topic/horizontal-trend-lines-in-prorealtime/#post-178606

Visit Link
What is a Snippet? A snippet is a small, reusable chunk of code designed to solve specific tasks quickly. Think of it as a shortcut that helps you achieve your coding goals without reinventing the wheel. How to Use: Simply copy the snippet and paste it into your project where needed. Don't forget to tweak it to fit your context. Snippets are not just time-savers; they're also learning tools to help you become a more efficient coder.
Reiner Veteran
This author is like an anonymous function, present but not directly identifiable. More details on this code architect as soon as they exit 'incognito' mode.
Author’s Profile

Comments

Search Snippets

Showing some results...
Sorry, no result found!

Snippets Categories

global
35
indicator
133
strategy
171

Recent Snippets

How to Create a Simple MTF Trend Dashboard with EMA and SMA
indicator
This indicator builds a compact multi-timeframe (MTF) dashboard that shows whether price is trading above or below a [...]
How to Display Per-Bar Volume Accumulation in Real Time (Intrabar Updates)
global
This snippet tracks and displays the current bar’s accumulated volume while the bar is still forming, instead of only [...]
Ticks Counter: Count Tick Updates Per Bar on Tick or Time Charts
global
This snippet counts how many tick updates have occurred for the current bar by incrementing a per-bar counter on each [...]
How to Build a Step-Based Trailing Stop That Moves to Break-Even First
strategy
This snippet implements a step trailing stop that advances in fixed increments once price reaches predefined profit [...]
Utilizing Arrays to Track and Compare Indicator Values Within the Same Bar in ProBuilder
indicator
This ProBuilder code snippet demonstrates how to use arrays to compare the values of an indicator (RSI in this case) [...]
Logo Logo
Loading...