Topics

Forum Topics not found

Replies

amusleh
10 May 2022, 09:38

Hi,

Please post a job request or contact one of our consultants.


@amusleh

amusleh
10 May 2022, 09:37 ( Updated at: 10 May 2022, 09:42 )

Hi,

BeginInvokeOnMainThread executes your code as a promise in future without blocking, asynchronously on cBot/Indicator main thread.

It passes your action delegate to the cBot/Indicator main thread event loop.

What do you mean by waiting? do you mean blocking the calling thread until the execution of your passed code to BeginInvokeOnMainThread finish? 

There is only one way to wait, block your current thread by using a thread synchronization context like ManualResetEventSlim until cBot/Indicator thread execute your code.

You can avoid some of this issues, but the solutions are dependent on your circumstance and there is no general solution.


@amusleh

amusleh
09 May 2022, 09:03

Hi,

The screenshot from your logs tab is not readable, if there is any error please post it instead.

Or if possible post a sample cBot that can reproduce the issue.


@amusleh

amusleh
09 May 2022, 09:01

Hi,

You can't access the token there, only the application that you authorized can get the token via authentication code.

 


@amusleh

amusleh
09 May 2022, 08:59

Hi,

CPU usage can be related to lots of things, and you can't micro manage it.

When you load the bars of multiple symbols it subscribes to their incoming bars and that can increase slightly the CPU usage even if market is closed.

The cTrader CPU usage on Task manager is not just the amount of CPU cycles that is used by your cBot.


@amusleh

amusleh
09 May 2022, 08:53

Hi,

Right now this data is not available on Automate API, the only that you can use to get this data is Open API.

I recommend you to create a thread under suggestions section for adding a Symbol base and quote currencies to Automate API.

 


@amusleh

amusleh
09 May 2022, 07:30

Hi,

If you are using cTrader desktop then you can use Go To Date indicator: Go To Date Indicator | Algorithmic Forex Trading | cTrader Community


@amusleh

amusleh
06 May 2022, 13:28

RE:

Jobauma said:

Hi. :)

How to write from registry?

Thanks.

Best regards,

Johannes Hillestad Baumann

Hi,

Please create a new thread for your question.


@amusleh

amusleh
06 May 2022, 12:29

Hi,

1. On indicators Bars.Reloaded is not called at all on re-connection, because when cTrader re-connects it re-initializes the indicators and your indicator Initialize method will be called, for now Bars.Reloaded is only called on cBots, in future versions we will add some options to control the initialization of indicators on re-connect.

2. No, they don't remain, your indicator will be re-initialized and all previous calculated data will be lost, only interactive drawings remain on chart.

3. Yes, after reconnection your indicator previous instance is destroyed and a new instance is created, then new instance Initialize method is called and after that Calculate method for all bars on the chart.

 


@amusleh

amusleh
06 May 2022, 12:16

RE: RE: Custom Renko Chart (Non-Overlay)

steel.export said:

amusleh said:

Hi,

We fixed the issue, thanks for reporting.

 

Dear Mr. Ahmad,

Thanks for Fixing the Indicator.

Please also advice if it possible to have Candlestick Chart on Top, and Non-Overlay Renko chart at the bottom on the same page ?

Thanks & Best Regards,

Altaf

Hi,

No you can't have both chart types, both chart types must be Renko.


@amusleh

amusleh
06 May 2022, 08:58

Hi,

Bars.ClosePrices.Last(1) gives you the close price of last closed bar, not the close price of last bar which is not closed yet.

Bars.ClosePrices.LastValue or Bars.ClosePrices.Last(0) will give you the close price of last bar, which is not closed yet.

Bars.LastBar.Close is equivalent to Bars.ClosePrices.Last(0) / Bars.ClosePrices.LastValue. 


@amusleh

amusleh
06 May 2022, 08:55

Hi,

We will consider developing such an indicator.


@amusleh

amusleh
06 May 2022, 08:54

Hi,

We fixed the issue, thanks for reporting.


@amusleh

amusleh
05 May 2022, 14:17

RE: RE:

userUser said:

amusleh said:

Hi,

Please follow this guide: Debugging - cTrader Automate API Documentation (spotware.github.io)

Hi Ahmad,

I am not a new with debugger. I use debugger with cTrader 4.1 and VS2019. 

But there is some problem with cTrader 4.2 and VS2022. Symbols are not loading.

 

PS. I tried to start debugging in 2 ways : 

(1) from VS2022 break point -> compile -> debug

(2) with System.Diagnostics.Debugger.Launch()  method from cBot. 

It doesn't work for both ways.

Hi,

In version 4.2 debugging changed, as each cBot/Indicator instance runs on their own separate process.

The link I posted is the guide for debugging on new cTrader 4.2 version with Visual Studio 2022.

If you are seeing the symbol not loading page, just ignore it, switch to your indicator/cBot source code tab and you will be able to continue the execution and it will hit your breakpoints.


@amusleh

amusleh
05 May 2022, 14:15

Hi,

Please post a job request on Jobs page or contact one of our consultants.


@amusleh

amusleh
05 May 2022, 10:34

Hi,

I tested again on IC Markets m1 bars from 17/02/2021 - now, all positions had stop loss, try this:

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

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class Sample_cBot : Robot
    {
        public DOWNTRADEI DOWN;
        public UPTRADEI UP;

        protected override void OnStart()
        {
            DOWN = Indicators.GetIndicator<DOWNTRADEI>(0.0);
            UP = Indicators.GetIndicator<UPTRADEI>(0.0);

            PendingOrders.Filled += PendingOrders_Filled;
        }

        private void PendingOrders_Filled(PendingOrderFilledEventArgs obj)
        {
            if (obj.Position.StopLoss.HasValue == false)
            {
                Print("Position without stop loss");

                Stop();
            }
            else
            {
                Print("Position stop loss: {0}", obj.Position.StopLoss);
            }
        }

        protected override void OnBar()
        {
            if (DOWN.Result.Last(1) == 1)
            {
                var st = Math.Abs((DOWN.stoploss.LastValue - Bars.OpenPrices.Last(1)) / Symbol.PipSize);
                st = st + 2;

                PlaceStopOrder(TradeType.Sell, Symbol, 1000, Bars.OpenPrices.Last(1) - Symbol.PipSize * 0.5, "DOWNTRADE", st, st * 2, Server.Time.AddMinutes(59));
            }

            if (UP.Result.Last(1) == 2)
            {
                var st2 = Math.Abs((UP.stoploss.LastValue - Bars.OpenPrices.Last(1)) / Symbol.PipSize);
                st2 = st2 + 2;

                PlaceStopOrder(TradeType.Buy, Symbol, 1000, Bars.OpenPrices.Last(1) + Symbol.PipSize * 0.5, "UPTRADE", st2, st2 * 2, Server.Time.AddMinutes(59));
            }
        }
    }
}

If an order filled and it's position had no stop loss the bot will print "Position without stop loss" and stops.


@amusleh

amusleh
05 May 2022, 10:24

Hi,

You have to use outputs instead of IndicatorDataSeries fields, then you will be able to use your indicator on a cBot by referencing.

Also you can put the whole indicator code on a cBot, example:

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

namespace NewcBot2
{
    [Robot(AccessRights = AccessRights.None)]
    public class NewcBot2 : Robot
    {
        [Parameter("Show High,Low", DefaultValue = true)]
        public bool showHL { get; set; }

        private IndicatorDataSeries _haOpen;
        private IndicatorDataSeries _haClose;
        private IndicatorDataSeries _haHigh;
        private IndicatorDataSeries _haLow;

        protected override void OnStart()
        {
            _haOpen = CreateDataSeries();
            _haClose = CreateDataSeries();
            _haHigh = CreateDataSeries();
            _haLow = CreateDataSeries();
        }

        protected override void OnBar()
        {
            var index = Bars.Count - 2;

            var open = Bars.OpenPrices[index];
            var high = Bars.HighPrices[index];
            var low = Bars.LowPrices[index];
            var close = Bars.ClosePrices[index];

            var haClose = (open + high + low + close) / 4;

            if (double.IsNaN(_haOpen[index - 1]))
            {
                _haOpen[index - 1] = Bars.OpenPrices[index - 1];
            }

            var haOpen = (index > 0) ? (_haOpen[index - 1] + _haClose[index - 1]) / 2 : (open + close) / 2;
            var haHigh = Math.Max(Math.Max(high, haOpen), haClose);
            var haLow = Math.Min(Math.Min(low, haOpen), haClose);

            _haOpen[index] = haOpen;
            _haHigh[index] = haHigh;
            _haLow[index] = haLow;
            _haClose[index] = haClose;

            if (index < 4) return;

            var position = Positions.Find("MyBot");

            if (_haClose[index] > _haOpen[index] && _haClose[index - 1] < _haOpen[index - 1])
            {
                if (position != null && position.TradeType == TradeType.Sell) ClosePosition(position);

                ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.VolumeInUnitsMin, "MyBot");
            }
            else if (_haClose[index] < _haOpen[index] && _haClose[index - 1] > _haOpen[index - 1])
            {
                if (position != null && position.TradeType == TradeType.Buy) ClosePosition(position);

                ExecuteMarketOrder(TradeType.Sell, SymbolName, Symbol.VolumeInUnitsMin, "MyBot");
            }
        }
    }
}

The above cBot opens a buy position on start of green line and a sell position on start of red line, it closes the buy position on start of red line and the sell position on start of green line.

 


@amusleh

amusleh
05 May 2022, 10:06 ( Updated at: 05 May 2022, 10:54 )

Hi,

By Wining Trades it means those trades with a positive net profit, any trade that has a positive net profit will be considered a wining trade, and it will try to maximize that number.

Regarding multiple criteria, yes it's ranked from top to bottom and every criteria has equal weight, they get multiplied by each other and then divided:

// sign is either +1 or -1. if there is any criteria value less than 0 then sign will be -1 otherwise +1
fitness = sign *  criteriaToMaximizeMultipliedAbsoluteValue / criteriaToMinimizeMultipliedAbsoluteValue

You can calculate any metric you want to by using custom fitness, GetFitnessArgs gives you all data related to back test pass, and you can use that data to calculate any metric you want to.


@amusleh

amusleh
05 May 2022, 09:59

RE: RE: RE: ADX INDICATOR ALERT ON TELEGRAM

steel.export said:

Dear Mr. Ahmad,

Thanks for your reply.

This time Built is giving the below 2 Errors.

 

Error CS0029 Cannot implicitly convert type 'cAlgo.API.TimeFrame' to 'string' ADXwithAlert.

Error CS0029 Cannot implicitly convert type 'cAlgo.API.Internals.Symbol' to 'string' ADXwithAlert.

 

Please Advice.

Thanks & Best Regards,

Altaf

Hi,

You have to call the ToString method on them:

using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Alert;
using cAlgo.API.Alert.Models;

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class ADXwithAlert : Indicator
    {
        private AverageDirectionalMovementIndexRating _adx;
        private int _lastAlertBarIndex;

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

        [Parameter("Level", DefaultValue = 25, Group = "Alert")]
        public double AlertLevel { get; set; }

        [Parameter("Setup", DefaultValue = 25, Group = "Alert")]
        public bool AlertSetup { get; set; }

        [Output("ADX", LineColor = "Blue")]
        public IndicatorDataSeries Adx { get; set; }

        [Output("ADXR", LineColor = "Yellow")]
        public IndicatorDataSeries AdxR { get; set; }

        [Output("DI+", LineColor = "Green")]
        public IndicatorDataSeries DiPlus { get; set; }

        [Output("DI-", LineColor = "Red")]
        public IndicatorDataSeries DiMinus { get; set; }

        protected override void Initialize()
        {
            _adx = Indicators.AverageDirectionalMovementIndexRating(Periods);

            if (AlertSetup)
            {
                Notifications.ShowPopup();
            }
        }

        public override void Calculate(int index)
        {
            Adx[index] = _adx.ADX[index];
            AdxR[index] = _adx.ADXR[index];
            DiPlus[index] = _adx.DIPlus[index];
            DiMinus[index] = _adx.DIMinus[index];

            if (IsLastBar && _lastAlertBarIndex != index && Adx[index] > AlertLevel)
            {
                _lastAlertBarIndex = index;

                var type = string.Format("ADX above {0}", AlertLevel);

           AlertModel alert = new AlertModel
            {
                TimeFrame = TimeFrame.ToString(),
                Symbol = SymbolName,
                Price = Adx[index],
                TriggeredBy = "ADX with Alert",
                Type = type,
                Time = Server.Time
            };

                Notifications.TriggerAlert(alert);
            }
        }
    }
}

 


@amusleh