Indicator have a bug

Created at 06 Sep 2024, 11:43
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!
MA

magomanitr

Joined 06.09.2024

Indicator have a bug
06 Sep 2024, 11:43


Please help me solve for Telegram notification from the script below

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using System.Net;
using Telegram.Bot;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class SMATSMAEMA : Indicator
    {
        private MovingAverage _sma;
        private MovingAverage _ema;
        private MovingAverage _tma;
        private IndicatorDataSeries _tsma;
        private MovingAverage _wilderSmoothing;
        private IndicatorDataSeries WilderSmoothing;
        private int WilderSmoothingPeriod = 5;

        private StackPanel stackPanel;

        private TextBox _smaTextBox;
        private TextBox _emaTextBox;
        private TextBox _tmaTextBox;
        private TextBox _tsmaTextBox;

        // Declare signal point variables
        private Ellipse _smaSignalPoint;
        private Ellipse _emaSignalPoint;
        private Ellipse _tmaSignalPoint;
        private Ellipse _tsmaSignalPoint;

        private bool _buySignalSentForSMA = false;
        private bool _sellSignalSentForSMA = false;
        private bool _buySignalSentForEMA = false;
        private bool _sellSignalSentForEMA = false;
        private bool _buySignalSentForTMA = false;
        private bool _sellSignalSentForTMA = false;
        private bool _buySignalSentForTSMA = false;
        private bool _sellSignalSentForTSMA = false;

        [Parameter(DefaultValue = Orientation.Vertical)]
        public Orientation Orientation { get; set; }

        [Parameter("SMA Period", DefaultValue = 200)]
        public int SmaPeriod { get; set; }

        [Parameter("EMA Period", DefaultValue = 200)]
        public int EmaPeriod { get; set; }

        [Parameter("TMA Period", DefaultValue = 200)]
        public int TmaPeriod { get; set; }

        [Parameter("TSMA Period", DefaultValue = 200)]
        public int TsmaPeriod { get; set; }

        [Output("SMA", LineColor = "LawnGreen", PlotType = PlotType.Line)]
        public IndicatorDataSeries SmaResult { get; set; }

        [Output("EMA", LineColor = "OrangeRed", PlotType = PlotType.Line)]
        public IndicatorDataSeries EmaResult { get; set; }

        [Output("TMA", LineColor = "Blue", PlotType = PlotType.Line)]
        public IndicatorDataSeries TmaResult { get; set; }

        [Output("TSMA", LineColor = "Purple", PlotType = PlotType.Line)]
        public IndicatorDataSeries TsmaResult { get; set; }

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

        [Parameter("Buy Sound File", Group = "Notifications", DefaultValue = "C:/Windows/Media/buy.wav")]
        public string BuySoundFile { get; set; }

        [Parameter("Sell Sound File", Group = "Notifications", DefaultValue = "C:/Windows/Media/sell.wav")]
        public string SellSoundFile { get; set; }

        [Output("Sell Point", Color = Colors.Red, PlotType = PlotType.Points, Thickness = 0)]
        public IndicatorDataSeries SellSeries { get; set; }

        [Output("Buy Point", Color = Colors.Lime, PlotType = PlotType.Points, Thickness = 0)]
        public IndicatorDataSeries BuySeries { get; set; }

        [Parameter("Bot Token", DefaultValue = "", Group = "Telegram Notifications")]
        public string BotToken { get; set; }

        [Parameter("Chat ID", DefaultValue = "", Group = "Telegram Notifications")]
        public string ChatID { get; set; }

        [Parameter("Send a Telegram?", DefaultValue = false, Group = "Telegram Notifications")]
        public bool IncludeTelegram { get; set; }

        protected override void Initialize()
        {
            _sma = Indicators.SimpleMovingAverage(MarketSeries.Close, SmaPeriod);
            _ema = Indicators.ExponentialMovingAverage(MarketSeries.Close, EmaPeriod);
            _tma = Indicators.TriangularMovingAverage(MarketSeries.Close, TmaPeriod);
            _tsma = CreateDataSeries();
            _wilderSmoothing = Indicators.WellesWilderSmoothing(MarketSeries.Close, WilderSmoothingPeriod);
            WilderSmoothing = CreateDataSeries();

            ServicePointManager.Expect100Continue = true;
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            // Initialize StackPanel
            stackPanel = new StackPanel
            {
                Orientation = Orientation.Vertical,
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Bottom,
                BackgroundColor = Color.FromArgb(5, Color.White),
                Margin = 10
            };

            // Create signal panels for each MA type
            _smaTextBox = CreateTextBox();
            var smaSignalPanel = CreateSignalPanel(_smaTextBox, out _smaSignalPoint);

            _emaTextBox = CreateTextBox();
            var emaSignalPanel = CreateSignalPanel(_emaTextBox, out _emaSignalPoint);

            _tmaTextBox = CreateTextBox();
            var tmaSignalPanel = CreateSignalPanel(_tmaTextBox, out _tmaSignalPoint);

            _tsmaTextBox = CreateTextBox();
            var tsmaSignalPanel = CreateSignalPanel(_tsmaTextBox, out _tsmaSignalPoint);

            // Add signal panels to the main stack panel
            stackPanel.AddChild(smaSignalPanel);
            stackPanel.AddChild(emaSignalPanel);
            stackPanel.AddChild(tmaSignalPanel);
            stackPanel.AddChild(tsmaSignalPanel);

            Chart.AddControl(stackPanel);
        }

        public override void Calculate(int index)
        {
            // Calculate the moving averages
            SmaResult[index] = _sma.Result[index];
            EmaResult[index] = _ema.Result[index];
            TmaResult[index] = _tma.Result[index];
            CalculateTSMA(index);
            WilderSmoothing[index] = _wilderSmoothing.Result[index];

            // Check for crossover conditions
            CheckForSignals(index, SmaResult, "SMA");
            CheckForSignals(index, EmaResult, "EMA");
            CheckForSignals(index, TmaResult, "TMA");
            CheckForSignals(index, TsmaResult, "TSMA");
        }

        private void CalculateTSMA(int index)
        {
            if (index < TsmaPeriod)
                return;

            double sumX = 0;
            double sumY = 0;
            double sumXY = 0;
            double sumX2 = 0;

            for (int i = 0; i < TsmaPeriod; i++)
            {
                int x = i + 1;
                double y = MarketSeries.Close[index - i];

                sumX += x;
                sumY += y;
                sumXY += x * y;
                sumX2 += x * x;
            }

            double slope = (TsmaPeriod * sumXY - sumX * sumY) / (TsmaPeriod * sumX2 - sumX * sumX);
            double intercept = (sumY - slope * sumX) / TsmaPeriod;

            TsmaResult[index] = intercept - (slope / 300) * TsmaPeriod;
        }

        private TextBox CreateTextBox()
        {
            return new TextBox
            {
                Margin = 5,
                Text = "Waiting for Signal...",
                BackgroundColor = Color.Black,
                ForegroundColor = Color.Black,
                Width = 100,
                FontSize = 14,
                HorizontalAlignment = HorizontalAlignment.Left
            };
        }

        private StackPanel CreateSignalPanel(TextBox textBox, out Ellipse signalPoint)
        {
            signalPoint = new Ellipse
            {
                Width = 10,
                Height = 10,
                FillColor = Color.Gray,
                Margin = 5
            };

            var signalPanel = new StackPanel
            {
                Orientation = Orientation.Horizontal,
                Margin = 5
            };

            signalPanel.AddChild(signalPoint);
            

            return signalPanel;
        }

        private void UpdateTextBoxAndSignal(TextBox textBox, Ellipse signalPoint, string text, Color color)
        {
            textBox.Text = text;
            textBox.BackgroundColor = color;
            signalPoint.FillColor = color;
        }

        private void CheckForSignals(int index, IndicatorDataSeries maResult, string maType)
        {
            bool buySignal = WilderSmoothing[index] > maResult[index] && MarketSeries.Close[index - 1] >= maResult[index - 1];
            bool sellSignal = WilderSmoothing[index] < maResult[index] && MarketSeries.Close[index - 1] <= maResult[index - 1];

            TextBox targetTextBox = null;
            Ellipse targetSignalPoint = null;
            ref bool buySignalSent = ref _buySignalSentForSMA;
            ref bool sellSignalSent = ref _sellSignalSentForSMA;

            switch (maType)
            {
                case "SMA":
                    targetTextBox = _smaTextBox;
                    targetSignalPoint = _smaSignalPoint;
                    break;
                case "EMA":
                    targetTextBox = _emaTextBox;
                    targetSignalPoint = _emaSignalPoint;
                    buySignalSent = ref _buySignalSentForEMA;
                    sellSignalSent = ref _sellSignalSentForEMA;
                    break;
                case "TMA":
                    targetTextBox = _tmaTextBox;
                    targetSignalPoint = _tmaSignalPoint;
                    buySignalSent = ref _buySignalSentForTMA;
                    sellSignalSent = ref _sellSignalSentForTMA;
                    break;
                case "TSMA":
                    targetTextBox = _tsmaTextBox;
                    targetSignalPoint = _tsmaSignalPoint;
                    buySignalSent = ref _buySignalSentForTSMA;
                    sellSignalSent = ref _sellSignalSentForTSMA;
                    break;
            }

            if (targetTextBox == null || targetSignalPoint == null) return;

            if (buySignal && !buySignalSent)
            {
                UpdateTextBoxAndSignal(targetTextBox, targetSignalPoint, $"{maType} BUY", Color.LawnGreen);
                SendTelegramAndPlaySound(maType, "BUY", index, maResult);
                buySignalSent = true;
                sellSignalSent = false;
            }
            else if (sellSignal && !sellSignalSent)
            {
                UpdateTextBoxAndSignal(targetTextBox, targetSignalPoint, $"{maType} SELL", Color.OrangeRed);
                SendTelegramAndPlaySound(maType, "SELL", index, maResult);
                sellSignalSent = true;
                buySignalSent = false;
            }

            if (WilderSmoothing[index] < maResult[index] * 0.99 || WilderSmoothing[index] > maResult[index] * 1.01)
            {
                buySignalSent = false;
                sellSignalSent = false;
            }
        }
    



        private void SendTelegramAndPlaySound(string maType, string signal, int index, IndicatorDataSeries maResult)
        {
            if (IncludeTelegram)
            {
                SendTelegram(maType, Symbol.Name, BuySeries[index + 1] = maResult[index], TimeFrame.ToString(), $"{maType} {signal}");
            }
            if (PlaySound)
            {
                var soundFile = signal == "BUY" ? BuySoundFile : SellSoundFile;
                Notifications.PlaySound(soundFile);
            }
            Print($"{maType} {signal} Signal at {maResult[index]} on bar {index}");
        }

        private void AddTextToStackPanel(string text, Color color)
        {
            var textBox = new TextBox
            {
                Margin = 5,
                Text = text,
                BackgroundColor = color,
                ForegroundColor = Color.White,
                Width = 150,
                FontSize = 14, // Adjust font size here
                HorizontalAlignment = HorizontalAlignment.Left
            };

            stackPanel.AddChild(textBox);
        }

        public async void SendTelegram(string signalType, string symbolName, double bidPrice, string timeframe, string maType)
        {
            string telegramMessage = $"Signal: Possible {maType} {signalType}\nSymbol: {symbolName}\nBid Price: {Math.Round(bidPrice, 3).ToString()}\nTimeframe: {timeframe}";
        
            try
            {
                var bot = new TelegramBotClient(BotToken);
                await bot.SendTextMessageAsync(ChatID, telegramMessage);
            }
            catch (Exception ex)
            {
                Print("ERROR: " + ex.Message);
            }
        }
    }
}


@magomanitr
Replies

PanagiotisCharalampous
06 Sep 2024, 11:50

Hi there,

Please provide a clear description of what the problem is.

Best regards,

Panagiotis


@PanagiotisCharalampous

magomanitr
06 Sep 2024, 11:58 ( Updated at: 08 Sep 2024, 05:09 )

RE: RE: Indicator have a bug

magomanitr said: 

PanagiotisCharalampous said: 

Hi there,

Please provide a clear description of what the problem is.

Best regards,

Panagiotis

 

I am coding for Telegram notification when there is cross over on Moving Averages.
When I Build the indicator is says ‘Telegram.Bot is not supported’

Even the following it gives a red underline
using Telegram.Bot; 


@magomanitr

PanagiotisCharalampous
09 Sep 2024, 05:46

RE: RE: RE: Indicator have a bug

magomanitr said: 

magomanitr said: 

PanagiotisCharalampous said: 

Hi there,

Please provide a clear description of what the problem is.

Best regards,

Panagiotis

 

I am coding for Telegram notification when there is cross over on Moving Averages.
When I Build the indicator is says ‘Telegram.Bot is not supported’

Even the following it gives a red underline
using Telegram.Bot; 

Make sure you are using the .Net Compiler


@PanagiotisCharalampous