Topics

Forum Topics not found

Replies

amusleh
16 May 2022, 09:59

RE: Can't establish new connection with old proxies

budda_dan2020 said:

Hi Amusleh,

we've got same problem. 

already established connections are still working, but we tried to restart the app and couldn't connection wit old proxy address.

Is it not better for clients that you enable to establish new connection with OLD and new proxies?

Because we have 20 apps and to change all these apps make us not really happy.

Some apps are working with real money and hundreds followers are copying our accounts.

Kind regards

Hi,

We will update you when the issue resolved, our previous proxies should work fine for now once the issue has been resolved.


@amusleh

amusleh
16 May 2022, 09:57 ( Updated at: 16 May 2022, 09:58 )

Hi,

There are several issues on your code, and you have to remember that Fractals are lagging indicator, and you have to access it's x previous values based on the period to passed to it.

Try this:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        private double _volumeInUnits;
        private Fractals _fractals;
        private SimpleMovingAverage _sma;

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

        [Parameter("Source")]
        public DataSeries Source { get; set; }

        [Parameter("Volume (Lots)", DefaultValue = 0.5)]
        public double VolumeInLots { get; set; }

        [Parameter("Stop Loss (Pips)", DefaultValue = 20)]
        public double StopLossInPips { get; set; }

        [Parameter("Take Profit (Pips)", DefaultValue = 60)]
        public double TakeProfitInPips { get; set; }

        [Parameter("Label", DefaultValue = "Sample")]
        public string Label { get; set; }

        private Position[] BotPositions
        {
            get { return Positions.FindAll(Label); }
        }

        protected override void OnStart()
        {
            _sma = Indicators.SimpleMovingAverage(Source, Period);
            _volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
            _fractals = Indicators.Fractals(5);
        }

        protected override void OnBar()
        {
            double close = Bars.ClosePrices.Last(1);

            double sma = _sma.Result.Last(1);

            double upfr = _fractals.UpFractal.Last(5);
            double dwfr = _fractals.DownFractal.Last(5);

            if (upfr < close)
            {
                ClosePositions(TradeType.Sell);

                if (sma < close && Positions.Count == 0)
                {
                    ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
                }
            }
            else if (dwfr > close)
            {
                ClosePositions(TradeType.Buy);

                if (sma > close && Positions.Count == 0)
                {
                    ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
                }
            }
        }

        private void ClosePositions(TradeType tradeType)
        {
            foreach (var position in BotPositions)
            {
                if (position.TradeType != tradeType)
                    continue;
                ClosePosition(position);
            }
        }
    }
}

 


@amusleh

amusleh
16 May 2022, 09:36

Hi,

The index is the current chart bars index, not the index of time frame that you loaded.

You have to change the index to the loaded time frame bars index first then use it, try this:

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]);

            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]);

            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
16 May 2022, 09:13

Hi,

Please post a job request or contact one of our consultant partners.


@amusleh

amusleh
16 May 2022, 09:12

RE:

bogdan.titomir said:

seems i know how to doing it, in method onStart just  run server if port hasn't listen

You can use TCP or Named pipe in case of communication in between internal processes.


@amusleh

amusleh
13 May 2022, 11:38

Hi,

I didn't understand exactly what you are looking for, but you can develop a cBot/indicator that will run upon cTrader desktop launch.

There is an option on cTrader automate that will auto restart your cBot when cTrader launched.


@amusleh

amusleh
13 May 2022, 11:18

RE: RE: still unable to connect to my live accounts

mcm187 said:

amusleh said:

Hi,

We are aware of this issue, it will be fixed as soon as possible.

Hi Amusleh do you have an estimated time for when this will be resolved? 

Three days have passed and I am still unable to connect to my live accounts?
it is very frustrating when I am managing several accounts and my investment portfolios doing nothing every day that I am unable to connect to them is  a major problem and costly

Hi,

We are still trying to resolve this issue on our Europe proxies, for the time being please try other proxies and flushing your system DNS cache.


@amusleh

amusleh
13 May 2022, 10:32

Hi,

Try this:

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

namespace cAlgo.Indicators

{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class IchimokuKinkoHyo : Indicator
    {
        private int _lastAlertBar;

        [Parameter(DefaultValue = 9)]
        public int periodFast { get; set; }

        [Parameter(DefaultValue = 26)]
        public int periodMedium { get; set; }

        [Parameter(DefaultValue = 52)]
        public int periodSlow { get; set; }

        [Parameter(DefaultValue = 26)]
        public int DisplacementChikou { get; set; }

        [Parameter(DefaultValue = 26)]
        public int DisplacementCloud { get; set; }

        [Parameter("Enable", DefaultValue = true, Group = "Alert")]
        public bool IsAlertEnabled { get; set; }

        [Parameter("Sound File Path", Group = "Alert")]
        public string SoundFilePath { get; set; }

        [Parameter("From Email", Group = "Alert")]
        public string FromEmail { get; set; }

        [Parameter("To Email", Group = "Alert")]
        public string ToEmail { get; set; }

        [Output("TenkanSen", Color = Colors.Red)]
        public IndicatorDataSeries TenkanSen { get; set; }

        [Output("Kijunsen", Color = Colors.Blue)]
        public IndicatorDataSeries KijunSen { get; set; }

        [Output("ChikouSpan", Color = Colors.DarkViolet)]
        public IndicatorDataSeries ChikouSpan { get; set; }

        [Output("SenkouSpanB", Color = Colors.Red, LineStyle = LineStyle.Lines)]
        public IndicatorDataSeries SenkouSpanB { get; set; }

        [Output("SenkouSpanA", Color = Colors.Green, LineStyle = LineStyle.Lines)]
        public IndicatorDataSeries SenkouSpanA { get; set; }

        private double maxfast, minfast, maxmedium, minmedium, maxslow, minslow;

        public override void Calculate(int index)

        {
            if ((index < periodFast) || (index < periodSlow)) { return; }

            maxfast = MarketSeries.High[index];

            minfast = MarketSeries.Low[index];

            maxmedium = MarketSeries.High[index];

            minmedium = MarketSeries.Low[index];

            maxslow = MarketSeries.High[index];

            minslow = MarketSeries.Low[index];

            for (int i = 0; i < periodFast; i++)

            {
                if (maxfast < MarketSeries.High[index - i]) { maxfast = MarketSeries.High[index - i]; }

                if (minfast > MarketSeries.Low[index - i]) { minfast = MarketSeries.Low[index - i]; }
            }

            for (int i = 0; i < periodMedium; i++)

            {
                if (maxmedium < MarketSeries.High[index - i]) { maxmedium = MarketSeries.High[index - i]; }

                if (minmedium > MarketSeries.Low[index - i]) { minmedium = MarketSeries.Low[index - i]; }
            }

            for (int i = 0; i < periodSlow; i++)

            {
                if (maxslow < MarketSeries.High[index - i]) { maxslow = MarketSeries.High[index - i]; }

                if (minslow > MarketSeries.Low[index - i]) { minslow = MarketSeries.Low[index - i]; }
            }

            TenkanSen[index] = (maxfast + minfast) / 2;

            KijunSen[index] = (maxmedium + minmedium) / 2;

            ChikouSpan[index - DisplacementChikou] = MarketSeries.Close[index];

            SenkouSpanA[index + DisplacementCloud] = (TenkanSen[index] + KijunSen[index]) / 2;

            SenkouSpanB[index + DisplacementCloud] = (maxslow + minslow) / 2;

            if (IsLastBar && IsAlertEnabled && _lastAlertBar != index)
            {
                _lastAlertBar = index;

                if (TenkanSen.HasCrossedAbove(KijunSen, 0))
                {
                    Notifications.PlaySound(SoundFilePath);
                    Notifications.SendEmail(FromEmail, ToEmail, "Ichimoku kinku hyo Alert | Bullish", "TenkanSen crossed above KijunSen");
                }
                else if (TenkanSen.HasCrossedBelow(KijunSen, 0))
                {
                    Notifications.PlaySound(SoundFilePath);
                    Notifications.SendEmail(FromEmail, ToEmail, "Ichimoku kinku hyo Alert | Bearish", "TenkanSen crossed below KijunSen");
                }
            }
        }
    }
}

For email notification to work you have to first configure your cTrader email notification settings.


@amusleh

amusleh
13 May 2022, 10:21

Hi,

We can only help you if you post a code sample that can reproduce this issue.

Please post the code for your cBot and the custom indicator you are using.


@amusleh

amusleh
13 May 2022, 10:19

Hi,

GetIndexByTime method returns the nearest bar index based on the date time you passed to it, if there is no bar for your passed date time then it will return -1.

Please post a indicator/cBot code sample that can reproduce the issue, then we will be able to help you.

 


@amusleh

amusleh
12 May 2022, 12:24

RE:

noob7 said:

@amusleh

Because of this change Ive lost over 100 euro.

Why you didnt notify me about this breaking changes?

Hi,

The change was not a breaking change, our old proxies are still working and they resolve to new nearest proxies.

We are still investigating the connection issue.


@amusleh

amusleh
12 May 2022, 10:38

Hi,

We updated API proxies: Proxies / Endpoints - cTrader Open API (spotware.github.io)

Please use the new proxies based on your region, and if you faced any connection issue try individual proxies of a region and then report the issue by providing the proxy you used.


@amusleh

amusleh
12 May 2022, 09:06 ( Updated at: 12 May 2022, 09:07 )

Hi,

A closed position is a deal/trade, you have to use either Positions.Closed event or History collection, the deal has both entry time and close time.


@amusleh

amusleh
12 May 2022, 09:05

Hi,

There is no way to do this via API or programmatically.

You can open a thread on suggestions section for such a feature.


@amusleh

amusleh
11 May 2022, 14:50

RE: RE:

ctid2032775 said:

amusleh said:

Hi,

Thanks for providing the details, we are investigating the issue now and if we were able to replicate it we will fix it.

Hi,

any news regarding this issue?

Thx & BR
Christian

Hi,

We tried everything to reproduce the issue you are facing but we couldn't.


@amusleh

amusleh
11 May 2022, 14:16

Hi,

We are aware of this issue, it will be fixed as soon as possible.


@amusleh

amusleh
11 May 2022, 10:43 ( Updated at: 21 Dec 2023, 09:22 )

Hi,

Open API returns Symbol min/max/step volumes in cents, you have to divide it by 100 to get the volume in symbol quote asset unit.

The US 30 minimum volume is 0.01 contracts on my TopFX demo account:

Not 1 contract, maybe you are using two different accounts for Open API and cTrader desktop.

 


@amusleh

amusleh
11 May 2022, 10:04

Hi,

No, you can't, you can create a proxy class for communication between your DLL services and indicator/cBot.

You can also reference automate API assembly and use the base Indicator or Robot interfaces on your own assemblies (DLLs).


@amusleh

amusleh
10 May 2022, 10:59 ( Updated at: 10 May 2022, 11:06 )

RE:

darcome said:

Ok, as I wrote, this is what I am already doing.

I was hoping BeginInvokeOnMainThread could become an async function, so that it could be awaited.

 

Thank you anyway for the answer!

Hi,

Awaiting doesn't solve the issue, the code that calls BeginInvokeOnMainThread is executed on one thread and the action delegate you pass to BeginInvokeOnMainThread will run on cBot/Indicator main thread.

Even if you await, the cBot/Indicator thread has to either execute the continuation code by itself or dispatch it to the calling thread, during this time the calling thread will be free to do other stuff which is the benefit of asynchronous programming as you can do some other task while your passed action delegate to BeginInvokeOnMainThread is waiting to be executed.

To solve this issue you can create a pub/sub messaging agent, with a post method that will take your action delegate to BeginInvokeOnMainThread, and once the action delegate is executed by cBot/indicator main thread the agent will notify you, you can use .NET channels to avoid thread synchronization.

You can use such a wrapper over BeginInvokeOnMainThread to even get retuned values from your code that will be executed on cBot/Indicator main thread.

 


@amusleh

amusleh
10 May 2022, 09:41

Hi,

Try this:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SampleBreakoutRobot : Robot
    {
        [Parameter("Source")]
        public DataSeries Source { get; set; }

        [Parameter("Band Height (pips)", DefaultValue = 40.0, MinValue = 0)]
        public double BandHeightPips { get; set; }

        [Parameter("Stop Loss (pips)", DefaultValue = 20, MinValue = 1)]
        public int StopLossInPips { get; set; }

        [Parameter("Take Profit (pips)", DefaultValue = 40, MinValue = 1)]
        public int TakeProfitInPips { get; set; }

        [Parameter("Volume", DefaultValue = 10000, MinValue = 1000)]
        public int Volume { get; set; }

        [Parameter("Bollinger Bands Deviations", DefaultValue = 2)]
        public int Deviations { get; set; }

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

        [Parameter("Bollinger Bands MA Type")]
        public MovingAverageType MAType { get; set; }

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

        [Parameter("Enabled", DefaultValue = false, Group = "Single Direction")]
        public bool IsSingleDirection { get; set; }

        [Parameter("Trade Type", Group = "Single Direction")]
        public TradeType SingleDirectionTradeType { get; set; }

        private BollingerBands bollingerBands;
        private string label = "SampleBreakoutRobot";
        private int consolidation;

        protected override void OnStart()
        {
            bollingerBands = Indicators.BollingerBands(Source, Periods, Deviations, MAType);
        }

        protected override void OnBar()
        {
            var top = bollingerBands.Top.Last(1);
            var bottom = bollingerBands.Bottom.Last(1);

            if (top - bottom <= BandHeightPips * Symbol.PipSize)
            {
                consolidation = consolidation + 1;
            }
            else
            {
                consolidation = 0;
            }

            if (consolidation >= ConsolidationPeriods)
            {
                if (Symbol.Ask > top && (IsSingleDirection == false || SingleDirectionTradeType == TradeType.Buy))
                {
                    ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, label, StopLossInPips, TakeProfitInPips);

                    consolidation = 0;
                }
                else if (Symbol.Bid < bottom && (IsSingleDirection == false || SingleDirectionTradeType == TradeType.Sell))
                {
                    ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, label, StopLossInPips, TakeProfitInPips);

                    consolidation = 0;
                }
            }
        }
    }
}

 


@amusleh