Email notificatons: how to amend email message subject

Created at 05 Jan 2018, 16:45
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
ST

Stokes Bay

Joined 18.04.2016

Email notificatons: how to amend email message subject
05 Jan 2018, 16:45


Hi,

Thanks to Paul Hayes, Clickalgo for the following code which triggers an alert based on volatility settings. I have included a line to send an email once the alert is triggered but cannot work out how to amend the email subject to include which symbol has triggered the alert.

Secondly, I want to restrict the emails to just 1 per bar (or some other restriction) since my current method sends an email on each tick if triggered (yet I do want the alert to continue to monitor each tick).

Can anyone help?

// -------
// PURPOSE
// -------
// Alerts user when there is high volatility in the market over a period of seconds.
// Userful signal when not looking at charts or when not at computer, configurable audible sound alerts for each currency.
// Good for scalping.

// Author: Paul Hayes    
// Date:   24/12/2015
// Version 1.5
//
// Coding Guidlines: https://github.com/dotnet/corefx/wiki/Framework-Design-Guidelines-Digest
//
// Bug fix: display formatting issue.

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class ScalpersBuddy : Indicator
    {
        #region user defined parameters

        [Parameter("Alert ON", DefaultValue = true)]
        public bool AlertOn { get; set; }

        [Parameter("Sound ON", DefaultValue = true)]
        public bool PlaySound { get; set; }

        [Parameter("Volatility Pips", DefaultValue = 10, MaxValue = 200000, MinValue = 1)]
        public int VolatilityPips { get; set; }

        [Parameter("Media File", DefaultValue = "c:\\windows\\media\\notify.wav")]
        public string MediaFile { get; set; }

        [Parameter("Display Position, 1-8", DefaultValue = 2, MinValue = 1, MaxValue = 3)]
        public int WarningPostion { get; set; }

        [Parameter("Warning Color", DefaultValue = "Red")]
        public string WarningColor { get; set; }

        [Parameter("Show Volatility", DefaultValue = true)]
        public bool ShowVolatility { get; set; }

        [Parameter("Show Spread", DefaultValue = true)]
        public bool ShowSpread { get; set; }

        [Parameter("Show Depth of Market", DefaultValue = true)]
        public bool ShowDepthOfMarket { get; set; }

        [Parameter("Spread Color", DefaultValue = "White")]
        public string SpreadColor { get; set; }

        #endregion

        #region Private properties

        private MarketSeries mSeries;
        private StaticPosition position;
        private Colors warningTextColor;
        private Colors spreadTextColor;
        private bool errorOccured = false;
        private string lowerPosition = string.Empty;
        private MarketDepth marketDepth;

        #endregion

        const string errorMsg = "\n\n\n\n\n Scalpers Buddy Indicator: An error has occurred, view log events window for more information.";


        #region cTrader Events

        protected override void Initialize()
        {
            try
            {
                // Get the time-frame series of data
                mSeries = MarketData.GetSeries(Symbol, TimeFrame.Minute);
                warningTextColor = (Colors)Enum.Parse(typeof(Colors), WarningColor, true);
                spreadTextColor = (Colors)Enum.Parse(typeof(Colors), SpreadColor, true);

                if (ShowDepthOfMarket)
                {
                    //  Get Market Depth
                    marketDepth = MarketData.GetMarketDepth(Symbol);

                    // subscribe to event Updated
                    marketDepth.Updated += MarketDepthUpdated;
                }

            } catch (Exception e)
            {
                errorOccured = true;
                Print("Scalpers Buddy: " + e.Message);
            }

            // position alert message on screen
            switch (WarningPostion)
            {
                case 1:
                    position = StaticPosition.TopLeft;
                    break;
                case 2:
                    position = StaticPosition.TopCenter;
                    break;
                case 3:
                    position = StaticPosition.TopRight;
                    break;
                case 4:
                    position = StaticPosition.Right;
                    lowerPosition = "\n\n";
                    break;
                case 5:
                    position = StaticPosition.BottomRight;
                    lowerPosition = "\n\n";
                    break;
                case 6:
                    position = StaticPosition.BottomCenter;
                    lowerPosition = "\n\n";
                    break;
                case 7:
                    position = StaticPosition.BottomLeft;
                    lowerPosition = "\n\n";
                    break;
                case 8:
                    position = StaticPosition.Left;
                    lowerPosition = "\n\n";
                    break;
                default:
                    position = StaticPosition.TopLeft;
                    break;
            }
        }

        public override void Calculate(int index)
        {
            if (errorOccured)
            {
                ChartObjects.DrawText("error-label", errorMsg, StaticPosition.TopCenter, Colors.Red);
                return;
            }

            // get the last highest price value
            double high = (mSeries.High.LastValue);
            // get the last lowest price value
            double low = (mSeries.Low.LastValue);

            // difference between high and low divided by the current instruments pip size = sudden movement in pips
            double pips = (high - low) / Symbol.PipSize;

            string pipsVolatility = "(Bar h-l: " + pips.ToString("0.00") + " pips)";

            // display error message to screen.
            if (ShowVolatility)
            {
                ChartObjects.DrawText("volatilityMsg", pipsVolatility += lowerPosition, position, spreadTextColor);
            }

            // if pip movement > volatility setting 
            if (Math.Ceiling(pips) > VolatilityPips)
            {
                if (AlertOn)
                {
                    ChartObjects.DrawText("alertMsg", pipsVolatility, position, warningTextColor);
                    Notifications.SendEmail("xxx@hotmail.com", "xxx@gmail.com", "Symbol name here", "Volatility trigger hit");
                }

                if (PlaySound)
                {
                    if (MediaFile != string.Empty)
                        Notifications.PlaySound(MediaFile);
                }
            }
            else
            {
                ChartObjects.RemoveObject("alertMsg");
            }

            // if user wants to see the current bid/ask spread size, * feature separate from volatility alert.
            if (ShowSpread)
            {
                var spread = Math.Round(Symbol.Spread / Symbol.PipSize, 2);
                string s = string.Format("{0:N2}", spread);

                ChartObjects.DrawText("spreadMsg", "\nSpread: " + s, position, spreadTextColor);
            }
        }

        #endregion

        #region market depth

        private void MarketDepthUpdated()
        {
            double bidVolume = 0;
            double askVolume = 0;

            foreach (var entry in marketDepth.BidEntries)
            {
                double dVolume = Math.Round(entry.Volume / 1000000.0, 2);
                bidVolume += dVolume;
            }

            foreach (var entry in marketDepth.AskEntries)
            {
                double dVolume = Math.Round(entry.Volume / 1000000.0, 2);
                askVolume += dVolume;
            }


        }

        #endregion
    }
}

 


@Stokes Bay
Replies

Stokes Bay
08 Jan 2018, 18:53

here is the answer below for those interested:

 

// -------
// PURPOSE
// -------
// Alerts user when there is high volatility in the market over a period of seconds.
// Userful signal when not looking at charts or when not at computer, configurable audible sound alerts for each currency.
// Good for scalping.

// Author: Paul Hayes    
// Date:   24/12/2015
// Version 1.5
//
// Coding Guidlines: https://github.com/dotnet/corefx/wiki/Framework-Design-Guidelines-Digest
//
// Bug fix: display formatting issue.

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class ScalpersBuddy : Indicator
    {
        #region user defined parameters

        [Parameter("Alert ON", DefaultValue = true)]
        public bool AlertOn { get; set; }

        [Parameter("Sound ON", DefaultValue = true)]
        public bool PlaySound { get; set; }

        [Parameter("Volatility Pips", DefaultValue = 10, MaxValue = 200000, MinValue = 1)]
        public int VolatilityPips { get; set; }

        [Parameter("Media File", DefaultValue = "c:\\windows\\media\\notify.wav")]
        public string MediaFile { get; set; }

        [Parameter("Display Position, 1-8", DefaultValue = 2, MinValue = 1, MaxValue = 3)]
        public int WarningPostion { get; set; }

        [Parameter("Warning Color", DefaultValue = "Red")]
        public string WarningColor { get; set; }

        [Parameter("Show Volatility", DefaultValue = true)]
        public bool ShowVolatility { get; set; }

        [Parameter("Show Spread", DefaultValue = true)]
        public bool ShowSpread { get; set; }

        [Parameter("Show Depth of Market", DefaultValue = true)]
        public bool ShowDepthOfMarket { get; set; }

        [Parameter("Spread Color", DefaultValue = "White")]
        public string SpreadColor { get; set; }

        #endregion

        #region Private properties

        private MarketSeries mSeries;
        private StaticPosition position;
        private Colors warningTextColor;
        private Colors spreadTextColor;
        private bool errorOccured = false;
        private string lowerPosition = string.Empty;
        private MarketDepth marketDepth;

        #endregion

        const string errorMsg = "\n\n\n\n\n Scalpers Buddy Indicator: An error has occurred, view log events window for more information.";


        #region cTrader Events

        protected override void Initialize()
        {
            try
            {
                // Get the time-frame series of data
                mSeries = MarketData.GetSeries(Symbol, TimeFrame.Minute);
                warningTextColor = (Colors)Enum.Parse(typeof(Colors), WarningColor, true);
                spreadTextColor = (Colors)Enum.Parse(typeof(Colors), SpreadColor, true);

                if (ShowDepthOfMarket)
                {
                    //  Get Market Depth
                    marketDepth = MarketData.GetMarketDepth(Symbol);

                    // subscribe to event Updated
                    marketDepth.Updated += MarketDepthUpdated;
                }

            } catch (Exception e)
            {
                errorOccured = true;
                Print("Scalpers Buddy: " + e.Message);
            }

            // position alert message on screen
            switch (WarningPostion)
            {
                case 1:
                    position = StaticPosition.TopLeft;
                    break;
                case 2:
                    position = StaticPosition.TopCenter;
                    break;
                case 3:
                    position = StaticPosition.TopRight;
                    break;
                case 4:
                    position = StaticPosition.Right;
                    lowerPosition = "\n\n";
                    break;
                case 5:
                    position = StaticPosition.BottomRight;
                    lowerPosition = "\n\n";
                    break;
                case 6:
                    position = StaticPosition.BottomCenter;
                    lowerPosition = "\n\n";
                    break;
                case 7:
                    position = StaticPosition.BottomLeft;
                    lowerPosition = "\n\n";
                    break;
                case 8:
                    position = StaticPosition.Left;
                    lowerPosition = "\n\n";
                    break;
                default:
                    position = StaticPosition.TopLeft;
                    break;
            }
        }

        public override void Calculate(int index)
        {
            if (errorOccured)
            {
                ChartObjects.DrawText("error-label", errorMsg, StaticPosition.TopCenter, Colors.Red);
                return;
            }

            // get the last highest price value
            double high = (mSeries.High.LastValue);
            // get the last lowest price value
            double low = (mSeries.Low.LastValue);

            // difference between high and low divided by the current instruments pip size = sudden movement in pips
            double pips = (high - low) / Symbol.PipSize;

            string pipsVolatility = "(Bar h-l: " + pips.ToString("0.00") + " pips)";

            // display error message to screen.
            if (ShowVolatility)
            {
                ChartObjects.DrawText("volatilityMsg", pipsVolatility += lowerPosition, position, spreadTextColor);
            }

            // if pip movement > volatility setting 
            if (Math.Ceiling(pips) > VolatilityPips)
            {
                if (AlertOn)
                {
                    ChartObjects.DrawText("alertMsg", pipsVolatility, position, warningTextColor);
                    Notifications.SendEmail("xxx@hotmail.com", "xxx@gmail.com", Symbol.Code + " Volatility trigger hit", "Volatility trigger hit");
                }

                if (PlaySound)
                {
                    if (MediaFile != string.Empty)
                        Notifications.PlaySound(MediaFile);
                }
            }
            else
            {
                ChartObjects.RemoveObject("alertMsg");
            }

            // if user wants to see the current bid/ask spread size, * feature separate from volatility alert.
            if (ShowSpread)
            {
                var spread = Math.Round(Symbol.Spread / Symbol.PipSize, 2);
                string s = string.Format("{0:N2}", spread);

                ChartObjects.DrawText("spreadMsg", "\nSpread: " + s, position, spreadTextColor);
            }
        }

        #endregion

        #region market depth

        private void MarketDepthUpdated()
        {
            double bidVolume = 0;
            double askVolume = 0;

            foreach (var entry in marketDepth.BidEntries)
            {
                double dVolume = Math.Round(entry.Volume / 1000000.0, 2);
                bidVolume += dVolume;
            }

            foreach (var entry in marketDepth.AskEntries)
            {
                double dVolume = Math.Round(entry.Volume / 1000000.0, 2);
                askVolume += dVolume;
            }


        }

        #endregion
    }
}

 


@Stokes Bay