Skip to content

How to Draw Andrews' Pitchfork

Andrews' Pitchfork is a popular technical analysis tool used, sometimes with other indicators, to identify potential support and resistance levels in a trending market. These levels serve as a critical foundation for successful trading strategies, giving traders clarity, structure and confidence in their decisions.

In this article and its accompanying video, you will learn how to create a cBot that draws Andrews' Pitchfork on a chart and code the pitchfork to update itself as the chart changes.

Draw Andrews' Pitchfork on a Chart

Andrews' Pitchfork consists of a median line (centerline) and two parallel lines that form a channel. These objects help traders visualise trends, forecast price movements and identify potential entry and exit points for trades.

Andrews' Pitchfork is drawn on a price chart using three key points: a high, a low, and a subsequent high or low point. Price movement within this channel often oscillates between the upper and lower lines, while the median line serves as a reversion point.

Let’s create a cBot that draws an uptrending Andrews' Pitchfork, which typically requires two lows and a high in between. The reverse is the case for a downtrending Andrews' Pitchfork: two highs and a low in between would be needed.

In cTrader Algo, click the 'New' button to create a cBot and input its name.

Andrews's Pitchfork requires six parameters to store the following: indices of the high and two lows, two minimum prices and a high price. Declare the six parameters.

1
2
3
4
5
6
private int _highIndex;
private int _lowIndex1;
private int _lowIndex2;
private double _max;
private double _min1;
private double _min2;

Detect the two minimum prices and the high price needed for the pitchfork points.

1
2
3
_max = Bars.HighPrices.Maximum(50);
_min1 = Bars.LowPrices.Minimum(50);
_min2 = Bars.LowPrices.Minimum(10);

cTrader Algo allows you to define the time location through methods providing either the absolute time or the relative bar index. The method used to draw the pitchfork on the chart introduces the relevant overrides. In this case, we chose the relative bar index.

Write the code to detect the indices of the high and low prices.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
for (int i = 0; i <= 50; i++)
{
    if (Bars.HighPrices.Last(i) == _max)
        _highIndex = Bars.Count - i - 1;
}

for (int i = 0; i <= 50; i++)
{
    if (Bars.LowPrices.Last(i) == _min1)
        _lowIndex1 = Bars.Count - i - 1;
}

for (int i = 0; i <= 10; i++)
{
    if (Bars.LowPrices.Last(i) == _min2)
        _lowIndex2 = Bars.Count - i - 1;
}

Draw the pitchfork on the chart.

1
Chart.DrawAndrewsPitchfork("AndrewsPitchfork", _lowIndex1, _min1, _highIndex, _max, _lowIndex2, _min2, Color.Red);

You can copy the full code below:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
using System;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None, AddIndicators = true)]
    public class AndrewsPitchfork : Robot
    {
        private int _highIndex;
        private int _lowIndex1;
        private int _lowIndex2;
        private double _max;
        private double _min1;
        private double _min2;

        protected override void OnStart()
        {
            _max = Bars.HighPrices.Maximum(50);
            _min1 = Bars.LowPrices.Minimum(50);
            _min2 = Bars.LowPrices.Minimum(10);

            for (int i = 0; i <= 50; i++)
            {
                if (Bars.HighPrices.Last(i) == _max)
                    _highIndex = Bars.Count - i - 1;
            }

            for (int i = 0; i <= 50; i++)
            {
                if (Bars.LowPrices.Last(i) == _min1)
                    _lowIndex1 = Bars.Count - i - 1;
            }

            for (int i = 0; i <= 10; i++)
            {
                if (Bars.LowPrices.Last(i) == _min2)
                    _lowIndex2 = Bars.Count - i - 1;
            }

            Chart.DrawAndrewsPitchfork("AndrewsPitchfork", _lowIndex1, _min1, _highIndex, _max, _lowIndex2, _min2, Color.Red);

        }

        protected override void OnTick()
        {
            // Handle price updates here
        }

        protected override void OnStop()
        {
            // Handle cBot stop here
        }
    }
}

Use the Ctrl+B hotkey or click 'Build' to build the cBot.

Add a local instance of the cBot by clicking 'Add Instance', selecting the 'Locally' option and then clicking 'Add Instance'.

Click the instance and navigate to the 'Backtesting' tab. Select a period for the backtesting, enable the 'Visual Mode' option and then click the play icon.

You should see the Andrews' Pitchfork drawn on the chart.

Update Andrews' Pitchfork

Return to the 'Algo' app and code the cBot to update the pitchfork as the chart changes.

Create a new method to draw the pitchfork and move the original logic into that method.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
private void DrawAndrewsPitchfork()
{
    _max = Bars.HighPrices.Maximum(50);
    _min1 = Bars.LowPrices.Minimum(50);
    _min2 = Bars.LowPrices.Minimum(10);

    for (int i = 0; i <= 50; i++)
    {
        if (Bars.HighPrices.Last(i) == _max)
            _highIndex = Bars.Count - i - 1;
    }

    for (int i = 0; i <= 50; i++)
    {
        if (Bars.LowPrices.Last(i) == _min1)
            _lowIndex1 = Bars.Count - i - 1;
    }

    for (int i = 0; i <= 10; i++)
    {
        if (Bars.LowPrices.Last(i) == _min2)
            _lowIndex2 = Bars.Count - i - 1;
    }

    if (_lowIndex1 < _highIndex && _highIndex < _lowIndex2)
        Chart.DrawAndrewsPitchfork("AndrewsPitchfork", _lowIndex1, _min1, _highIndex, _max, _lowIndex2, _min2, Color.Red);
}

Call the new method in the OnBar() method.

1
2
3
4
protected override void OnBar()
{
    DrawAndrewsPitchfork();
}

Since only uptrend setups are needed, write the conditional logic that verifies that minimums and maximums are in the correct order.

1
2
if (_lowIndex1 < _highIndex && _highIndex < _lowIndex2)
    Chart.DrawAndrewsPitchfork("AndrewsPitchfork", _lowIndex1, _min1, _highIndex, _max, _lowIndex2, _min2, Color.Red);

You can copy the full code below:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using System;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None, AddIndicators = true)]
    public class AndrewsPitchfork : Robot
    {
        private int _highIndex;
        private int _lowIndex1;
        private int _lowIndex2;
        private double _max;
        private double _min1;
        private double _min2;

        protected override void OnStart()
        {

        DrawAndrewsPitchfork(); 

        }

        private void DrawAndrewsPitchfork() 
        {
           _max = Bars.HighPrices.Maximum(50);
            _min1 = Bars.LowPrices.Minimum(50);
            _min2 = Bars.LowPrices.Minimum(10);

            for (int i = 0; i <= 50; i++)
            {
                if (Bars.HighPrices.Last(i) == _max)
                    _highIndex = Bars.Count - i - 1;
            }

            for (int i = 0; i <= 50; i++)
            {
                if (Bars.LowPrices.Last(i) == _min1)
                    _lowIndex1 = Bars.Count - i - 1;
            }

            for (int i = 0; i <= 10; i++)
            {
                if (Bars.LowPrices.Last(i) == _min2)
                    _lowIndex2 = Bars.Count - i - 1;
            }

            if (_lowIndex1 < _highIndex && _highIndex < _lowIndex2)
                 Chart.DrawAndrewsPitchfork("AndrewsPitchfork", _lowIndex1, _min1, _highIndex, _max, _lowIndex2, _min2, Color.Red);
        }

        protected override void OnBar()
        {
            DrawAndrewsPitchfork(); 
        }

        protected override void OnStop()
        {
            // Handle cBot stop here
        }
    }
}

Build the cBot again and then backtest it.

Increase the speed of the visual mode and click the play icon.

This time, you should see how the pitchfork is constantly redrawn as the chart changes.

Summary

This article has explained how to draw Andrews' Pitchfork on a symbol chart and code the pitchfork to update itself as the chart changes. To learn more about the cTrader Algo API, see our documentation and API Reference or post a question on our forum.

Subscribe to our YouTube channel