Category Trend  Published on 27/08/2018

2 Supertrend indicators on 1 chart

Description

V.2

added discription on how to modify the behavior of the indicator

- added the possibilty to alert you on screen, with sound and by email (with special thanks to afhacker)

(added parts are in Bolt)

This is a modification on the Supertrend indicator of spka111.

This indicator projects 2 Supertrend indicators on 1 chart with customisable parameters. It will also display the high or low of the last changes above/below the candle that caused the change.

You can change the behavior of the Supertrend indicator by modyfing "_averageTrueRangelong" and "_averageTrueRangeshort" in the "Initialize()" part. Delete the ".WilderSmoothing". Insert a "." after "MovingAverageType". It will show you all the options you can change it to. This will affect the behavior of the indicator slightly and you can use it to fit your tradingstyle.

To let the indicator part send you emails, alert you on screen or play a soundalert I used a method developed by afhacker. He created an alert popup window. You can find his project here: https://ctrader.com/algos/cbots/show/1692. Here you will find all the info you need to make this work.

I will show you the Alert-lines I added to this algorithm to make it so it will create alerts on this indicator. The line you are looking for begins with "Alert.Factory.Trigger". The text between brackets e.g. "Buy Long"  you can change to what you like that the alert will display. As afhacker describes is that the time it will show in the popup window and emails are in UTC. You can this in the popup alert settings to your liking.

Thank you afhacker for creating this great project!

// Test Notifications on chart
            {
                var value = MarketSeries.Close[index - 1];
                if (Functions.HasCrossedAbove(_upBufferlong, value, 1))
                {
                    var name = "BuyLong";
                    var high = MarketSeries.High[index - 1];
                    var text = high.ToString();
                    var xPos = index - 1;
                    var yPos = high;
                    var vAlign = VerticalAlignment.Top;
                    var hAlign = HorizontalAlignment.Center;
                    ChartObjects.DrawText(name, text, xPos, yPos, vAlign, hAlign, Colors.Lime);
                    Alert.Factory.Trigger(TradeType.Buy, Symbol, MarketSeries.TimeFrame, Server.Time.AddHours(1), "Buy Long");
                }
            }

            {
                var value = MarketSeries.Close[index - 1];
                if (Functions.HasCrossedBelow(_downBufferlong, value, 1))
                {
                    var name = "SellLong";
                    var low = MarketSeries.Low[index - 1];
                    var text = low.ToString();
                    var xPos = index - 1;
                    var yPos = low;
                    var vAlign = VerticalAlignment.Bottom;
                    var hAlign = HorizontalAlignment.Center;
                    ChartObjects.DrawText(name, text, xPos, yPos, vAlign, hAlign, Colors.PeachPuff);
                    Alert.Factory.Trigger(TradeType.Sell, Symbol, MarketSeries.TimeFrame, Server.Time.AddHours(1), "Sell Long");
                }
            }

            // Test Notifications on chart
            {
                var value = MarketSeries.Close[index - 1];
                if (Functions.HasCrossedAbove(_upBuffershort, value, 1))
                {
                    var name = "BuyShort";
                    var high = MarketSeries.High[index - 1];
                    var text = high.ToString();
                    var xPos = index - 1;
                    var yPos = high;
                    var vAlign = VerticalAlignment.Top;
                    var hAlign = HorizontalAlignment.Center;
                    ChartObjects.DrawText(name, text, xPos, yPos, vAlign, hAlign, Colors.Green);
                    Alert.Factory.Trigger(TradeType.Buy, Symbol, MarketSeries.TimeFrame, Server.Time.AddHours(1), "Buy Short");
                }
            }

            {
                var value = MarketSeries.Close[index - 1];
                if (Functions.HasCrossedBelow(_downBuffershort, value, 1))
                {
                    var name = "SellShort";
                    var low = MarketSeries.Low[index - 1];
                    var text = low.ToString();
                    var xPos = index - 1;
                    var yPos = low;
                    var vAlign = VerticalAlignment.Bottom;
                    var hAlign = HorizontalAlignment.Center;
                    ChartObjects.DrawText(name, text, xPos, yPos, vAlign, hAlign, Colors.Red);
                    Alert.Factory.Trigger(TradeType.Sell, Symbol, MarketSeries.TimeFrame, Server.Time.AddHours(1), "Sell Short");
                }
            }

I will upload the new indicator with email notifications when I get this working.


using System;
using cAlgo.API;
using cAlgo.API.Indicators;

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    //change to FullAccess to use alerts
    public class SupertrendDoubleWilderSmoothing : Indicator
    {
        [Parameter(DefaultValue = 50)]
        public int LongPeriod { get; set; }

        [Parameter(DefaultValue = 10.0)]
        public double LongMultiplier { get; set; }

        [Parameter(DefaultValue = 20)]
        public int ShortPeriod { get; set; }

        [Parameter(DefaultValue = 5.0)]
        public double ShortMultiplier { get; set; }

        [Output("UpTrendLong", Color = Colors.Green, PlotType = PlotType.Points, Thickness = 3)]
        public IndicatorDataSeries UpTrendLong { get; set; }

        [Output("DownTrendLong", Color = Colors.Red, PlotType = PlotType.Points, Thickness = 3)]
        public IndicatorDataSeries DownTrendLong { get; set; }

        [Output("UpTrendShort", Color = Colors.Green, PlotType = PlotType.Points, Thickness = 3)]
        public IndicatorDataSeries UpTrendShort { get; set; }

        [Output("DownTrendShort", Color = Colors.Red, PlotType = PlotType.Points, Thickness = 3)]
        public IndicatorDataSeries DownTrendShort { get; set; }

        private IndicatorDataSeries _upBufferlong;
        private IndicatorDataSeries _downBufferlong;
        private IndicatorDataSeries _upBuffershort;
        private IndicatorDataSeries _downBuffershort;
        private AverageTrueRange _averageTrueRangelong;
        private AverageTrueRange _averageTrueRangeshort;
        private int[] _trendlong;
        private int[] _trendshort;
        private bool _changeofTrendlong;
        private bool _changeofTrendshort;

        protected override void Initialize()
        {
            //Algoline here
            _trendlong = new int[1];
            _trendshort = new int[1];
            _upBufferlong = CreateDataSeries();
            _downBufferlong = CreateDataSeries();
            _upBuffershort = CreateDataSeries();
            _downBuffershort = CreateDataSeries();
            _averageTrueRangelong = Indicators.AverageTrueRange(LongPeriod, MovingAverageType.WilderSmoothing);
            _averageTrueRangeshort = Indicators.AverageTrueRange(ShortPeriod, MovingAverageType.WilderSmoothing);
        }

        public override void Calculate(int index)
        {
            // Init
            UpTrendLong[index] = double.NaN;
            DownTrendLong[index] = double.NaN;
            UpTrendShort[index] = double.NaN;
            DownTrendShort[index] = double.NaN;

            double median = (MarketSeries.High[index] + MarketSeries.Low[index]) / 2;
            double atrlong = _averageTrueRangelong.Result[index];
            double atrshort = _averageTrueRangeshort.Result[index];

            _upBufferlong[index] = median + LongMultiplier * atrlong;
            _downBufferlong[index] = median - LongMultiplier * atrlong;
            _upBuffershort[index] = median + ShortMultiplier * atrshort;
            _downBuffershort[index] = median - ShortMultiplier * atrshort;


            if (index < 1)
            {
                _trendlong[index] = 1;
                return;
            }

            Array.Resize(ref _trendlong, _trendlong.Length + 1);

            // Main Logic
            if (MarketSeries.Close[index] > _upBufferlong[index - 1])
            {
                _trendlong[index] = 1;
                if (_trendlong[index - 1] == -1)
                    _changeofTrendlong = true;
            }
            else if (MarketSeries.Close[index] < _downBufferlong[index - 1])
            {
                _trendlong[index] = -1;
                if (_trendlong[index - 1] == -1)
                    _changeofTrendlong = true;
            }
            else if (_trendlong[index - 1] == 1)
            {
                _trendlong[index] = 1;
                _changeofTrendlong = false;
            }
            else if (_trendlong[index - 1] == -1)
            {
                _trendlong[index] = -1;
                _changeofTrendlong = false;
            }

            if (_trendlong[index] < 0 && _trendlong[index - 1] > 0)
                _upBufferlong[index] = median + (LongMultiplier * atrlong);
            else if (_trendlong[index] < 0 && _upBufferlong[index] > _upBufferlong[index - 1])
                _upBufferlong[index] = _upBufferlong[index - 1];

            if (_trendlong[index] > 0 && _trendlong[index - 1] < 0)
                _downBufferlong[index] = median - (LongMultiplier * atrlong);
            else if (_trendlong[index] > 0 && _downBufferlong[index] < _downBufferlong[index - 1])
                _downBufferlong[index] = _downBufferlong[index - 1];

            // Draw Indicator
            if (_trendlong[index] == 1)
            {

                UpTrendLong[index] = _downBufferlong[index];
                if (_changeofTrendlong)
                {
                    UpTrendLong[index - 1] = DownTrendLong[index - 1];
                    _changeofTrendlong = false;
                }
            }
            else if (_trendlong[index] == -1)
            {

                DownTrendLong[index] = _upBufferlong[index];
                if (_changeofTrendlong)
                {
                    DownTrendLong[index - 1] = UpTrendLong[index - 1];
                    _changeofTrendlong = false;
                }

            }

            if (index < 1)
            {
                _trendshort[index] = 1;
                return;
            }

            Array.Resize(ref _trendshort, _trendshort.Length + 1);

            // Main Logic
            if (MarketSeries.Close[index] > _upBuffershort[index - 1])
            {
                _trendshort[index] = 1;
                if (_trendshort[index - 1] == -1)
                    _changeofTrendshort = true;
            }
            else if (MarketSeries.Close[index] < _downBuffershort[index - 1])
            {
                _trendshort[index] = -1;
                if (_trendshort[index - 1] == -1)
                    _changeofTrendshort = true;
            }
            else if (_trendshort[index - 1] == 1)
            {
                _trendshort[index] = 1;
                _changeofTrendshort = false;
            }
            else if (_trendshort[index - 1] == -1)
            {
                _trendshort[index] = -1;
                _changeofTrendshort = false;
            }

            if (_trendshort[index] < 0 && _trendshort[index - 1] > 0)
                _upBuffershort[index] = median + (ShortMultiplier * atrshort);
            else if (_trendshort[index] < 0 && _upBuffershort[index] > _upBuffershort[index - 1])
                _upBuffershort[index] = _upBuffershort[index - 1];

            if (_trendshort[index] > 0 && _trendshort[index - 1] < 0)
                _downBuffershort[index] = median - (ShortMultiplier * atrshort);
            else if (_trendshort[index] > 0 && _downBuffershort[index] < _downBuffershort[index - 1])
                _downBuffershort[index] = _downBuffershort[index - 1];

            // Draw Indicator
            if (_trendshort[index] == 1)
            {

                UpTrendShort[index] = _downBuffershort[index];
                if (_changeofTrendshort)
                {
                    UpTrendShort[index - 1] = DownTrendShort[index - 1];
                    _changeofTrendshort = false;
                }
            }
            else if (_trendshort[index] == -1)
            {

                DownTrendShort[index] = _upBuffershort[index];
                if (_changeofTrendshort)
                {
                    DownTrendShort[index - 1] = UpTrendShort[index - 1];
                    _changeofTrendshort = false;
                }
            }

            // Test Notifications on chart
            {
                var value = MarketSeries.Close[index - 1];
                if (Functions.HasCrossedAbove(_upBufferlong, value, 1))
                {
                    var name = "BuyLong";
                    var high = MarketSeries.High[index - 1];
                    var text = high.ToString();
                    var xPos = index - 1;
                    var yPos = high;
                    var vAlign = VerticalAlignment.Top;
                    var hAlign = HorizontalAlignment.Center;
                    ChartObjects.DrawText(name, text, xPos, yPos, vAlign, hAlign, Colors.Lime);
                    //Alertline here
                }
            }

            {
                var value = MarketSeries.Close[index - 1];
                if (Functions.HasCrossedBelow(_downBufferlong, value, 1))
                {
                    var name = "SellLong";
                    var low = MarketSeries.Low[index - 1];
                    var text = low.ToString();
                    var xPos = index - 1;
                    var yPos = low;
                    var vAlign = VerticalAlignment.Bottom;
                    var hAlign = HorizontalAlignment.Center;
                    ChartObjects.DrawText(name, text, xPos, yPos, vAlign, hAlign, Colors.PeachPuff);
                    //Alertline here
                }
            }

            // Test Notifications on chart
            {
                var value = MarketSeries.Close[index - 1];
                if (Functions.HasCrossedAbove(_upBuffershort, value, 1))
                {
                    var name = "BuyShort";
                    var high = MarketSeries.High[index - 1];
                    var text = high.ToString();
                    var xPos = index - 1;
                    var yPos = high;
                    var vAlign = VerticalAlignment.Top;
                    var hAlign = HorizontalAlignment.Center;
                    ChartObjects.DrawText(name, text, xPos, yPos, vAlign, hAlign, Colors.Green);
                    //Alertline here
                }
            }

            {
                var value = MarketSeries.Close[index - 1];
                if (Functions.HasCrossedBelow(_downBuffershort, value, 1))
                {
                    var name = "SellShort";
                    var low = MarketSeries.Low[index - 1];
                    var text = low.ToString();
                    var xPos = index - 1;
                    var yPos = low;
                    var vAlign = VerticalAlignment.Bottom;
                    var hAlign = HorizontalAlignment.Center;
                    ChartObjects.DrawText(name, text, xPos, yPos, vAlign, hAlign, Colors.Red);
                    //Alertline here
                }
            }

        }
    }
}


VI
Vince

Joined on 04.12.2017

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: SupertrendDoubleWilderSmoothing.algo
  • Rating: 0
  • Installs: 3704
Comments
Log in to add a comment.
IA
IandelMar · 4 years ago

Hello you can add all MA Types, i only see one. WHat is when the Price comes? Can i change the colour. THanks

afhacker's avatar
afhacker · 5 years ago

You don't have to change timezone manually, the user can change timezone in alert popup settings.