Topics

Forum Topics not found

Replies

amusleh
24 May 2022, 10:42

Hi,

What do you mean by stop? do you mean stopping the cBot itself?


@amusleh

amusleh
24 May 2022, 10:41

RE: RE:

123123 said:

amusleh said:

Hi,

When you scroll to the left cTrader automatically loads more data, there is no need for coding anything.

If it's not behaving like that then something is wrong, can you tell me which broker you are using?

Hi,

Something definitely wrong because I have never experienced this on cTrader, the broker is FTMO.

Hi,

Can you reproduce this same issue on other brokers cTrader desktops?

Maybe your broker has that much data for that symbol, and there is no more historical data.


@amusleh

amusleh
24 May 2022, 10:40

RE:

Jiri said:

Hi @amusleh,

Thanks for the response. It appears to me that the prior version of cTrader was checking the parameter type only if the class was decorated with the IndicatorAttribute. This makes sense because of the rendering UI components. But if there is a non-public indicator used internally only, without the UI, why would it require the limited parameter type? It does not feel like this was a bug, everything was working as expected. Can you suggest a workaround to pass custom parameter types that would be assigned prior to the Initialize state?

Hi,

It's definitely a bug on cTrader 4.2 that allows you to use not support parameter type.

You are using Parameter attribute in a way that is not meant to be used nor documented.

And you are also using GetIndicator incorrectly, it should only be used when you are using a referenced external indicator, not an indicator that resides on your current indicator assembly.

Regarding a solution, it's very simple, change your indicator design, use API members properly, why you need another indicator inside your current indicator assembly?

The problem you are trying to solve is you want to exchange data between two indicators, you can use static properties for it which is the simplest option.

 If you need a sample check our Synchronized Indicators:

 


@amusleh

amusleh
24 May 2022, 10:28

Hi,

This works fine on both cTrader 4.1 and 4.2:

using System;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
using System.Linq;

namespace cAlgo
{
    [Indicator("Support and Resistance At Price", IsOverlay = true, AccessRights = AccessRights.None)]
    public class SRAtPrice : Indicator
    {
        private double extremeHigh = 0;
        private double extremeLow = 0;
        private double dayHi = 0;
        private double dayLo = 0;
        private SortedList<double, int> prices = new SortedList<double, int>();
        private IList<Zone> zones = new List<Zone>();

        private const string ExtremeHighName = "ExtremeHigh";
        private const string ExtremeLowName = "ExtremeLow";
        private const string DayHighName = "DayHigh";
        private const string DayLowName = "DayLow";

        [Parameter("Periods", DefaultValue = 100)]
        public int Periods { get; set; }

        [Parameter("Show Extreme H/L", DefaultValue = true)]
        public bool ShowExtremeHL { get; set; }

        [Parameter("Show Day H/L", DefaultValue = true)]
        public bool ShowDayHL { get; set; }

        [Parameter("Required Hits", DefaultValue = 0)]
        public int RequiredHits { get; set; }

        [Parameter("Zone Size", DefaultValue = 2)]
        public int ZoneSize { get; set; }

        [Parameter("Max Lines In Zone", DefaultValue = 1)]
        public int MaxLinesInZone { get; set; }

        [Output("Extreme H/L Style", Color = Colors.Red, LineStyle = LineStyle.DotsVeryRare)]
        public IndicatorDataSeries ExtremeHLStyle { get; set; }

        [Output("Day H/L Style", Color = Colors.Blue, LineStyle = LineStyle.DotsVeryRare)]
        public IndicatorDataSeries DayHLStyle { get; set; }

        [Output("S/R Style", Color = Colors.Orange, LineStyle = LineStyle.DotsVeryRare)]
        public IndicatorDataSeries SRStyle { get; set; }

        public override void Calculate(int index)
        {
            if (this.IsLastBar)
            {
                var currentOpenDate = this.MarketSeries.OpenTime[index].Date;
                var earliest = index - this.Periods;
                for (var i = index; i >= earliest; i--)
                {
                    if (i >= 0)
                    {
                        var high = this.MarketSeries.High[i];
                        var nextHigh = this.MarketSeries.High[i + 1];
                        var low = this.MarketSeries.Low[i];
                        var nextLow = this.MarketSeries.Low[i + 1];
                        this.extremeHigh = Math.Max(high, this.extremeHigh);
                        this.extremeLow = this.extremeLow == 0 ? low : Math.Min(low, this.extremeLow);

                        if (this.TimeFrame < TimeFrame.Minute)
                        {
                            if (this.MarketSeries.OpenTime[i].Date == currentOpenDate)
                            {
                                this.dayHi = Math.Max(high, this.dayHi);
                                this.dayLo = this.dayLo == 0 ? low : Math.Min(low, this.dayLo);
                            }
                        }

                        if (nextHigh <= high)
                        {
                            this.AddOrUpdatePrice(high);
                        }

                        if (nextLow >= low)
                        {
                            this.AddOrUpdatePrice(low);
                        }
                    }
                    else
                    {
                        break;
                    }
                }

                this.zones.Clear();
                var rangePipSize = (this.Symbol.PipSize * (double)this.ZoneSize);
                for (var i = this.extremeLow + rangePipSize; i < this.extremeHigh - rangePipSize; i += rangePipSize + this.Symbol.PipSize)
                {
                    this.zones.Add(new Zone
                    {
                        Start = i,
                        End = i + rangePipSize,
                        LinesRendered = 0
                    });
                }

                var chartObjectCopy = Chart.Objects.ToArray();

                foreach (var chartObject in chartObjectCopy)
                {
                    Chart.RemoveObject(chartObject.Name);
                }

                foreach (var price in this.prices.Keys)
                {
                    this.RenderSRIfRequred(price, this.prices[price]);
                }

                if (this.ShowExtremeHL)
                {
                    this.DrawExtremeHigh();
                    this.DrawExtremeLow();
                }

                if (this.TimeFrame < TimeFrame.Minute && this.ShowDayHL)
                {
                    this.DrawDayHigh();
                    this.DrawDayLow();
                }
            }
        }

        private void RenderSRIfRequred(double price, int count)
        {
            if (count < this.RequiredHits)
            {
                return;
            }

            foreach (var range in this.zones)
            {
                if (price >= range.Start && price <= range.End)
                {
                    if (range.LinesRendered != this.MaxLinesInZone)
                    {
                        range.LinesRendered++;
                        this.DrawSR(price);
                    }
                    return;
                }
            }
        }

        private void AddOrUpdatePrice(double priceValue)
        {
            if (this.prices.ContainsKey(priceValue))
            {
                this.prices[priceValue]++;
            }
            else
            {
                this.prices.Add(priceValue, 1);
            }
        }

        private void DrawExtremeHigh()
        {
            this.DrawExtreme(ExtremeHighName, this.extremeHigh);
        }

        private void DrawExtremeLow()
        {
            this.DrawExtreme(ExtremeLowName, this.extremeLow);
        }

        private void DrawDayHigh()
        {
            this.DrawDay(DayHighName, this.dayHi);
        }

        private void DrawDayLow()
        {
            this.DrawDay(DayLowName, this.dayLo);
        }

        private void DrawExtreme(string name, double level)
        {
            var attribute = this.GetAttributeFrom<OutputAttribute>("ExtremeHLStyle");
            this.ChartObjects.DrawHorizontalLine(name, level, attribute.Color, attribute.Thickness, attribute.LineStyle);
        }

        private void DrawDay(string name, double level)
        {
            var attribute = this.GetAttributeFrom<OutputAttribute>("DayHLStyle");
            this.ChartObjects.DrawHorizontalLine(name, level, attribute.Color, attribute.Thickness, attribute.LineStyle);
        }

        private void DrawSR(double level)
        {
            var attribute = this.GetAttributeFrom<OutputAttribute>("SRStyle");
            this.ChartObjects.DrawHorizontalLine(string.Format("SR {0}", level), level, attribute.Color, attribute.Thickness, attribute.LineStyle);
        }

        private T GetAttributeFrom<T>(string propertyName)
        {
            var attrType = typeof(T);
            var property = this.GetType().GetProperty(propertyName);
            return (T)property.GetCustomAttributes(attrType, false).GetValue(0);
        }

        private class Price
        {
            internal double Value { get; set; }
            internal int Count { get; set; }
        }

        private class Zone
        {
            internal double Start { get; set; }
            internal double End { get; set; }
            internal int LinesRendered { get; set; }
        }
    }
}

 


@amusleh

amusleh
24 May 2022, 10:21

Hi,

Your code is not correct, your indicator should not work at all, not sure how it was working previously.

You are passing index + x to Bars Last method, the last method starts from 1 and it allows you to access bars in reverse order from most recent bars.

If you want to access three last bars you have to change it to:

using cAlgo.API;
using System.Linq;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class ThreeStrike : Indicator
    {
        [Parameter("Vertical Alignment", Group = "Position", DefaultValue = VerticalAlignment.Top)]
        public VerticalAlignment vAlignment { get; set; }

        [Parameter("Horizontal Alignment", Group = "Position", DefaultValue = HorizontalAlignment.Right)]
        public HorizontalAlignment hAlignment { get; set; }

        private ChartStaticText _text;

        protected override void Initialize()
        {
            _text = Chart.DrawStaticText("idtext_red", string.Empty, this.vAlignment, this.hAlignment, Color.Chocolate);
        }

        public override void Calculate(int index)
        {
            if (index < 3)
                return;

            var lastThreeBars = new Bar[]
            {
                Bars.Last(1),
                Bars.Last(2),
                Bars.Last(3)
            };

            if (lastThreeBars.All(bar => bar.Close > bar.Open))
            {
                _text.Text = "Wait For Red Engulfing";
                _text.Color = Color.Red;
                if (Bars.ClosePrices.Last(index) < Bars.OpenPrices.Last(index++))
                {
                    _text.Text = "Sell";
                    _text.Color = Color.Red;
                    Chart.DrawVerticalLine("Sell", Bars.OpenTimes.LastValue, Color.OrangeRed);
                }
            }
            else if (lastThreeBars.All(bar => bar.Close < bar.Open))
            {
                _text.Text = "Wait For Green Engulfing";
                _text.Color = Color.Green;

                if (Bars.ClosePrices.Last(index) > Bars.OpenPrices.Last(index++))
                {
                    _text.Text = "Buy";
                    _text.Color = Color.Green;
                    Chart.DrawVerticalLine("Buy", Bars.OpenTimes.LastValue, Color.LimeGreen);
                }
            }
            else
            {
                _text.Text = "Do Not Trade";
                _text.Color = Color.Gray;
            }
        }
    }
}

 


@amusleh

amusleh
24 May 2022, 10:16

Hi,

The received message is not well formatted, I can't read exactly what's inside it, please copy and post the exact message as text not image.


@amusleh

amusleh
24 May 2022, 10:14

RE: problem solved bij reinstalling cTrader

genappsforex said:

amusleh said:

Hi,

The lines are discontinuous:

After closing all copies of cTrader  and reinstalling cTrader  it It now gives the discontinuous lines as it should.

Hi,

The image I posted is from your own indicator and as you can see it was working fine on my system.


@amusleh

amusleh
24 May 2022, 10:13

Hi,

Then decrease the index by 1:

using cAlgo.API;

namespace cAlgo
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None, TimeZone = TimeZones.EAfricaStandardTime)]
    public class Spring : Indicator
    {
        [Output("Up Fractal", Color = Colors.Red, PlotType = PlotType.Points, Thickness = 5)]
        public IndicatorDataSeries UpFractal { get; set; }

        [Output("Down Fractal", Color = Colors.Blue, PlotType = PlotType.Points, Thickness = 5)]
        public IndicatorDataSeries DownFractal { get; set; }

        private Bars HSeries;

        protected override void Initialize()
        {
            HSeries = MarketData.GetBars(TimeFrame.Hour4);
        }

        public override void Calculate(int index)
        {
            if (index == 1)
                return;

            DrawUpFractal(index);
            DrawDownFractal(index);
        }

        private void DrawUpFractal(int index)
        {
            var hSeriesIndex = HSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]) - 1;

            int middleIndex = hSeriesIndex - 2;
            double middleValue = HSeries.ClosePrices[middleIndex];

            bool up = false;

            for (int i = 1; i < HSeries.ClosePrices.Count - 1; i++)
            {
                if (HSeries.ClosePrices[middleIndex] > HSeries.ClosePrices[middleIndex - 1] && HSeries.ClosePrices[middleIndex] > HSeries.ClosePrices[middleIndex + 1])
                {
                    up = true;
                    break;
                }
            }

            if (up)
                UpFractal[index] = middleValue;
        }

        private void DrawDownFractal(int index)
        {
            var hSeriesIndex = HSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]) - 1;

            int middleIndex = hSeriesIndex - 2;
            double middleValue = HSeries.ClosePrices[middleIndex];
            bool down = false;

            for (int i = 1; i < HSeries.ClosePrices.Count - 1; i++)
            {
                if (HSeries.ClosePrices[middleIndex] < HSeries.ClosePrices[middleIndex - 1] && HSeries.ClosePrices[middleIndex] < HSeries.ClosePrices[middleIndex + 1])
                {
                    down = true;
                    break;
                }
            }
            if (down)
                DownFractal[index] = middleValue;
        }
    }
}

 


@amusleh

amusleh
24 May 2022, 10:12

Hi,

I just tested this on M1 chart:

using System;
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;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.FullAccess)]
    public class NewcBot3 : Robot
    {
        protected override void OnStart()
        {
            Print("Started Bot...");
            
            var firstResult = ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.VolumeInUnitsMin);
            
            if (!firstResult.IsSuccessful)
            {
                Print("First Order not placed successfully");
            }
                      
            var secondResult = ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.VolumeInUnitsMin);
            
            if (!secondResult.IsSuccessful)
            {
                Print("Second Order not placed successfully");
            }
        }

        protected override void OnBar()
        {
            Print("OnBar Executed on.. " + Chart.TimeFrame);

            Print("Positions Length=" + Positions.Count);
            foreach (var position in Positions)
            {
                if (position.SymbolName != SymbolName) continue;
                
                Print("Position Entry Time=" + position.EntryTime);

                ClosePosition(position);
            }
        }
    }
}

All positions were closed without any issue.


@amusleh

amusleh
24 May 2022, 10:06

Hi,

The way you are using indicator parameters is not correct, it looks like it was working by luck and most probably it was a bug on version 4.1.

You can find the list of supported parameter types at: Indicator Code Samples - cTrader Automate API Documentation (spotware.github.io)

You can only use one of those types as a parameter.


@amusleh

amusleh
24 May 2022, 09:57

Hi,

We were able to reproduce the issue, we will investigate and update you soon.


@amusleh

amusleh
24 May 2022, 09:52

Hola,

Publique en la sección de sugerencias y en inglés.


@amusleh

amusleh
24 May 2022, 09:50

Hi,

Yes, every bot/indicator runs on their own threads.

In version 4.2 every instance of bots/indicators run on their separate process not just thread.


@amusleh

amusleh
24 May 2022, 08:45

Hi,

When you scroll to the left cTrader automatically loads more data, there is no need for coding anything.

If it's not behaving like that then something is wrong, can you tell me which broker you are using?


@amusleh

amusleh
24 May 2022, 08:44

RE: RE:

genappsforex said:

ctid2032775 said:

 A little bit strange is that as soon as I switch to .NET 6, run any bot and close the cTrader application the cTrader process is not terminated, as well.

I noticed that too, This behaviour eats Memory and CPU . Think they're forgetting to clean up/Close old threads.

Hi,

We can only help you if we were able to reproduce the issues you are facing, if we can't then there is no way for us to know what's going wrong.

 


@amusleh

amusleh
23 May 2022, 09:10

Hi,

There is no such feature on cTrader mobile.


@amusleh

amusleh
23 May 2022, 09:07

Hi,

You don't have to use FindAll method of Positions, you use it only when you want to filter the positions based on a label.

Change your code to:

using System;
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;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.FullAccess)]
    public class NewcBot3 : Robot
    {
        protected override void OnStart()
        {
            Print("Started Bot...");
        //    ExecuteMarketOrder(TradeType.Buy, SymbolName, 0.01, "");
        //    ExecuteMarketOrder(TradeType.Buy, SymbolName, 0.03, "");
        }

        protected override void OnBar()
        {
            Print("onBar Executed on.. " + Chart.TimeFrame);

            Print("Positions Length=" + Positions.Count);
            foreach (var position in Positions)
            {
                if (position.SymbolName != SymbolName) continue;
                Print("Position Entry Time=" + position.EntryTime);
                //   if (position.VolumeInUnits >= 0.02)
                //   {
                ClosePosition(position);
                //   }
            }
        }
    }
}

 


@amusleh

amusleh
23 May 2022, 09:03

Hi,

Where you get that error message? from 2calgo.com site? we don't support that service anymore.

If you want to convert another platform indicator/robot to cTrader post a job request on our jobs page or contact one of our consultant partners.

 


@amusleh

amusleh
23 May 2022, 09:00

RE: RE: RE:

fcarabat said:

algotrader said:

forexner12 said:

I have tried but not succesful 

Now your indicator is supported by 2calgo.com. Please try to convert it one more time.

 

I know this is a super old post, but i'm trying to convert the same sweetspots indicator with this page you mentioned, but it gives me back an error.  not sure what i'm doing wrong, i just copy and pasted the code.  any help would be greatly appreciated.

Hi,

You can post a job request on our jobs page or contact one of our consultant partners.


@amusleh

amusleh
23 May 2022, 08:59

Hi,

Please use suggestions section, create a thread there for your suggestion.


@amusleh