Help on Border..

Created at 08 Jul 2021, 05:09
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!
ngu1k's avatar

ngu1k

Joined 02.07.2021

Help on Border..
08 Jul 2021, 05:09


Hi, I try do build my own indicator. But I have problem with borders.

I've try to show support and resistance value in the top left corner of the chart.

with the condition if ema5 > ema13 the box color is green, and ema5 < ema 13 the box color is red. and put the support & resistance value (that calculate on calculate()) inside the box.

But I cannot made it possible. I've try put the border inside the calculate (), but it slow down my ctrader platform. Here is the sample of my code:

protected override void Initialize()
        {            
            source = CreateDataSeries();
            _ema5 = Indicators.ExponentialMovingAverage(source, periode_ema5);
            _ema24 = Indicators.ExponentialMovingAverage(source, periode_ema24);
            
            if (_ema5.Result.LastValue > _ema24.Result.LastValue)
                {
                    var_border = Color.Green;
                    var_background = Color.DarkGreen;
                }
                else
                {
                    var_border = Color.Red;
                    var_background = Color.DarkRed;
                }
            
            var border = new Border 
                {
                    BorderColor = var_border,
                    Opacity = 0.5,
                    BackgroundColor = var_background,
                    BorderThickness = 1.5,
                    HorizontalAlignment = HorizontalAlignment.Left,
                    VerticalAlignment = VerticalAlignment.Top,
                    CornerRadius = 10,
                    Width = 130,
                    Height = 55,
                    Margin = new Thickness(2, 30, 10, 10)
                };
                var stackPanel = new StackPanel 
                {
                    Orientation = Orientation.Vertical
                };
                stackPanel.AddChild(new TextBlock
                {
                    Text = support_resistance,    // I calculate this on Calculate(), but apparently cannot call that calculation
                    Margin = 5,
                    HorizontalAlignment = HorizontalAlignment.Center,
                    VerticalAlignment = VerticalAlignment.Center,
                    FontWeight = FontWeight.ExtraBold
                });
                border.Child = stackPanel;
                Chart.AddControl(border);
            

I'm new to coding, can anyone help me...

Thanks


@ngu1k
Replies

ngu1k
08 Jul 2021, 10:48 ( Updated at: 08 Jul 2021, 10:59 )

RE:

ngu1k said:

Hi, I try do build my own indicator. But I have problem with borders.

I've try to show support and resistance value in the top left corner of the chart.

with the condition if ema5 > ema13 the box color is green, and ema5 < ema 13 the box color is red. and put the support & resistance value (that calculate on calculate()) inside the box.

But I cannot made it possible. I've try put the border inside the calculate (), but it slow down my ctrader platform. Here is the sample of my code:

protected override void Initialize()
        {            
            source = CreateDataSeries();
            _ema5 = Indicators.ExponentialMovingAverage(source, periode_ema5);
            _ema24 = Indicators.ExponentialMovingAverage(source, periode_ema24);
            
            if (_ema5.Result.LastValue > _ema24.Result.LastValue)
                {
                    var_border = Color.Green;
                    var_background = Color.DarkGreen;
                }
                else
                {
                    var_border = Color.Red;
                    var_background = Color.DarkRed;
                }
            
            var border = new Border 
                {
                    BorderColor = var_border,
                    Opacity = 0.5,
                    BackgroundColor = var_background,
                    BorderThickness = 1.5,
                    HorizontalAlignment = HorizontalAlignment.Left,
                    VerticalAlignment = VerticalAlignment.Top,
                    CornerRadius = 10,
                    Width = 130,
                    Height = 55,
                    Margin = new Thickness(2, 30, 10, 10)
                };
                var stackPanel = new StackPanel 
                {
                    Orientation = Orientation.Vertical
                };
                stackPanel.AddChild(new TextBlock
                {
                    Text = support_resistance,    // I calculate this on Calculate(), but apparently cannot call that calculation
                    Margin = 5,
                    HorizontalAlignment = HorizontalAlignment.Center,
                    VerticalAlignment = VerticalAlignment.Center,
                    FontWeight = FontWeight.ExtraBold
                });
                border.Child = stackPanel;
                Chart.AddControl(border);
            

I'm new to coding, can anyone help me...

Thanks

I've figured out this problem, by create new fuction

public void DisplayUI ()

{

     if (_ema5.Result.LastValue > _ema24.Result.LastValue)
                {
                    var_border = Color.Green;
                    var_background = Color.DarkGreen;
                }
                else
                {
                    var_border = Color.Red;
                    var_background = Color.DarkRed;
                }
            
            var border = new Border 
                {
                    BorderColor = var_border,
                    Opacity = 0.5,
                    BackgroundColor = var_background,
                    BorderThickness = 1.5,
                    HorizontalAlignment = HorizontalAlignment.Left,
                    VerticalAlignment = VerticalAlignment.Top,
                    CornerRadius = 10,
                    Width = 130,
                    Height = 55,
                    Margin = new Thickness(2, 30, 10, 10)
                };
                var stackPanel = new StackPanel 
                {
                    Orientation = Orientation.Vertical
                };
                stackPanel.AddChild(new TextBlock
                {
                    Text = support_resistance,    // I calculate this on Calculate(), but apparently cannot call that calculation
                    Margin = 5,
                    HorizontalAlignment = HorizontalAlignment.Center,
                    VerticalAlignment = VerticalAlignment.Center,
                    FontWeight = FontWeight.ExtraBold
                });
                border.Child = stackPanel;
                Chart.AddControl(border);

}

Thanks

Is it the correct solution?


@ngu1k

amusleh
09 Jul 2021, 16:17

You have to define your controls as fields on your indicator class:

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class AWEMA : Indicator
    {
        private ExponentialMovingAverage _ema5, _ema24;

        private TextBlock _text;
        private Border _border;

        [Parameter("Source", DefaultValue = Price.High)]
        public Price Source { get; set; }


        protected override void Initialize()
        {
            var series = GetBaseSeries();

            _ema5 = Indicators.ExponentialMovingAverage(series, 5);
            _ema24 = Indicators.ExponentialMovingAverage(series, 24);


            _border = new Border 
            {
                BorderColor = Color.Red,
                Opacity = 0.5,
                BackgroundColor = Color.Yellow,
                BorderThickness = 1.5,
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Top,
                CornerRadius = 10,
                Width = 130,
                Height = 55,
                Margin = new Thickness(2, 30, 10, 10)
            };
            var stackPanel = new StackPanel 
            {
                Orientation = Orientation.Vertical
            };

            _text = new TextBlock 
            {
                Margin = 5,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                FontWeight = FontWeight.ExtraBold
            };

            stackPanel.AddChild(_text);

            _border.Child = stackPanel;

            Chart.AddControl(_border);
        }

        public override void Calculate(int index)
        {
            // You can set the text by using _text text block text property
            if (_ema5.Result.LastValue > _ema24.Result.LastValue)
            {
                _text.Text = "Green Text";

                _border.BorderColor = Color.Green;
                _border.BackgroundColor = Color.DarkGreen;
            }
            else
            {
                _text.Text = "Red Text";

                _border.BorderColor = Color.Red;
                _border.BackgroundColor = Color.DarkRed;
            }

        }

        private DataSeries GetBaseSeries()
        {
            switch (Source)
            {
                case Price.Open:
                    return Bars.OpenPrices;

                case Price.Close:
                    return Bars.ClosePrices;

                case Price.High:
                    return Bars.HighPrices;

                case Price.Low:
                    return Bars.LowPrices;

                case Price.Median:
                    return Bars.MedianPrices;

                case Price.Typical:
                    return Bars.TypicalPrices;

                case Price.Weighted:
                    return Bars.WeightedPrices;
                default:

                    return Bars.ClosePrices;
            }
        }
    }

    public enum Price
    {
        Open,
        Close,
        High,
        Low,
        Median,
        Typical,
        Weighted
    }
}

You don't have to redraw it on each tick.


@amusleh

ngu1k
10 Jul 2021, 16:48

RE:

amusleh said:

You have to define your controls as fields on your indicator class:

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class AWEMA : Indicator
    {
        private ExponentialMovingAverage _ema5, _ema24;

        private TextBlock _text;
        private Border _border;

        [Parameter("Source", DefaultValue = Price.High)]
        public Price Source { get; set; }


        protected override void Initialize()
        {
            var series = GetBaseSeries();

            _ema5 = Indicators.ExponentialMovingAverage(series, 5);
            _ema24 = Indicators.ExponentialMovingAverage(series, 24);


            _border = new Border 
            {
                BorderColor = Color.Red,
                Opacity = 0.5,
                BackgroundColor = Color.Yellow,
                BorderThickness = 1.5,
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Top,
                CornerRadius = 10,
                Width = 130,
                Height = 55,
                Margin = new Thickness(2, 30, 10, 10)
            };
            var stackPanel = new StackPanel 
            {
                Orientation = Orientation.Vertical
            };

            _text = new TextBlock 
            {
                Margin = 5,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                FontWeight = FontWeight.ExtraBold
            };

            stackPanel.AddChild(_text);

            _border.Child = stackPanel;

            Chart.AddControl(_border);
        }

        public override void Calculate(int index)
        {
            // You can set the text by using _text text block text property
            if (_ema5.Result.LastValue > _ema24.Result.LastValue)
            {
                _text.Text = "Green Text";

                _border.BorderColor = Color.Green;
                _border.BackgroundColor = Color.DarkGreen;
            }
            else
            {
                _text.Text = "Red Text";

                _border.BorderColor = Color.Red;
                _border.BackgroundColor = Color.DarkRed;
            }

        }

        private DataSeries GetBaseSeries()
        {
            switch (Source)
            {
                case Price.Open:
                    return Bars.OpenPrices;

                case Price.Close:
                    return Bars.ClosePrices;

                case Price.High:
                    return Bars.HighPrices;

                case Price.Low:
                    return Bars.LowPrices;

                case Price.Median:
                    return Bars.MedianPrices;

                case Price.Typical:
                    return Bars.TypicalPrices;

                case Price.Weighted:
                    return Bars.WeightedPrices;
                default:

                    return Bars.ClosePrices;
            }
        }
    }

    public enum Price
    {
        Open,
        Close,
        High,
        Low,
        Median,
        Typical,
        Weighted
    }
}

You don't have to redraw it on each tick.

Thanks... It worked....

But I have some question, what does public enum price {} for?


@ngu1k

amusleh
19 Jul 2021, 08:12

Hi,.

The Price enum is used to get the source of moving average from user via indicator parameters, we can use instead DataSeries for source parameter.


@amusleh

ngu1k
26 Jul 2021, 13:02

RE:

amusleh said:

Hi,.

The Price enum is used to get the source of moving average from user via indicator parameters, we can use instead DataSeries for source parameter.

thank you....


@ngu1k