Topics

Forum Topics not found

Replies

amusleh
28 Apr 2021, 11:11

RE: RE:

arturbrylka said:

amusleh said:

Hi,

The message tells you that the exception was thrown inside OnBar method, what you can do is put all your OnBar method code inside a try/catch block and check the thrown exception data or print its stacktrace, do this only for debugging and remove it when you find and fixed the issue because using general try/catch block for Exception type is not a good coding practice.

Hi Amusleh,

thank you for your comment. Just to avoid misunderstandings let me rephrase and underline the central point of my question:

Is there a possibility to print the stacktrace using the VS debug mode?

Kind regards

Artur

Not sure what do you mean by print the stacktrace using the VS debug mode.

If you are debugging and you have a breakpoint somewhere on your code you can step in/out to find the issue but that might get too much time and it depend on when your code throws the exception.

Instead put a try/cache block like this:

using cAlgo.API;
using System;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Bug : Robot
    {
        protected override void OnBar()
        {
            // Remove this cache block once you fixed the issue
            // Don't use general purpose try/catch blocks in production code
            try
            {
                // put all your OnBar code here
            }
            catch (Exception ex)
            {
                // Now you have the exception and you can do anything you want to with it
                Print(ex.StackTrace);
            }
        }
    }
}

 


@amusleh

amusleh
28 Apr 2021, 09:57

Hi,

You should iterate over your positions by using the Positions collection in OnTick method, not in OnPoisitionClosed event handler.


@amusleh

amusleh
28 Apr 2021, 09:53

Hi,

The message tells you that the exception was thrown inside OnBar method, what you can do is put all your OnBar method code inside a try/catch block and check the thrown exception data or print its stacktrace, do this only for debugging and remove it when you find and fixed the issue because using general try/catch block for Exception type is not a good coding practice.


@amusleh

amusleh
25 Apr 2021, 11:20 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE: Multiplying account balance by 100

rohingosling said:

Hi Amusleh,

Thank you, this helps enormously. 

One question regarding the code example you shared. The account balance is always multiplied by 100. Why is that? Is it to convert it to cents?

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Regards,

Rohin

 

For converting the Percent from decimal form to 0-100 form or vice versa.


@amusleh

amusleh
25 Apr 2021, 11:14

Hi,

Those are methods with "protected" access modifier, you can't call a protected method from another class, only the class itself or its derived classes can call a protected method.

Here is an example that might help you:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Test : Robot
    {
        protected override void OnStart()
        {
            var botController = new BotController(this);
        }

        protected override void OnTick()
        {
            // Put your core logic here
        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }

    public class BotController
    {
        private readonly Robot _robot;

        public BotController(Robot robot)
        {
            _robot = robot;
        }

        public void Stop()
        {
            _robot.Stop();
        }

        public IAccount GetAccount()
        {
            return _robot.Account;
        }
    }
}

These kind of topics aren't related to cTrader automate API, you have to learn C# and Google for similar issues in C#, you will find a lot of solutions.

There is a way to call protected methods via Reflection, Google and you will find lots of code examples for it.

 


@amusleh

amusleh
24 Apr 2021, 19:46 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE: RE:

swingfish said:

amusleh said:

 

Hi,

You can wait for the async method to complete by putting the thread on sleep and checking with a while loop like I did on previous example.

your example code did not prevent the calgo from shutting down ..

It does:

The cBot stopped approximately 5 seconds after OnStop method is called as you can see on the cBot logs.


@amusleh

amusleh
24 Apr 2021, 12:02

Hi,

Question 1:

Please check this file code: 

Question 2: Leverage decreases the cost of buying something for you and allows you to have more free equity, so you will be able to buy something with much lower equity of your account total available equity if you have higher leverage.

Question 3. PipValue is the amount of monetary value for one single Pip of a symbol in your account currency, you should use PipSize if you want to get the symbol Pip, in your case one Pip of USDJPY will cost you 0.0001 of your account currency for one single unit of volume, so it means if you buy 1 unit of volume of USDJPY one pip will cost you 0.0001 of your account currency.

Question 4. cTrader uses standard lot size and volume units, there is no micro, nano or other non-standard lot sizes, the minimum/maximum trading volume for symbols and all other symbols data are set by your broker.


@amusleh

amusleh
23 Apr 2021, 16:27

RE:

swingfish said:

Sorry i was not clear abou the issue at hand,

the calgo communicates with another device, which all works perfectly, I want to "inform" the other device that the bot is stopping

 

so in OnStop i sent a command to do so, the problem is the other device doesn't accept the Information if the connection is not completed.

when I click the stop button, the calgo sends the Async command, and then kills itself but the killing also severed the async connection so there is no ACK for the last transmission.

 

a workaround would be just to wait 500-1000 ms 

 

Hi,

You can wait for the async method to complete by putting the thread on sleep and checking with a while loop like I did on previous example.


@amusleh

amusleh
23 Apr 2021, 10:36 ( Updated at: 23 Apr 2021, 10:37 )

RE: RE:

tekASH said:

amusleh said:

If you call the ShowPopup method either it will show the popup or it will show an error message on your indicator/cBot logs if you set the "Logger.Trace" to "Print".

Please post your indicator code and then I will be able to help you.

sorry, I cant place code...it is private.

Just tell me what is logger.trace and where I enter Print. With your example.

 

Hi,

I close this thread here, code example:

using cAlgo.API;
using cAlgo.API.Alert;
using cAlgo.API.Alert.Utility;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class AlertTest : Indicator
    {
        private int _barIndex;

        protected override void Initialize()
        {
            Logger.Tracer = Print;
        }

        public override void Calculate(int index)
        {
            // Shows the popup on each new bar
            if (_barIndex != index && IsLastBar)
            {
                _barIndex = index;

                Notifications.ShowPopup();
            }
        }
    }
}

You can download the indicator file compiled with code from here: https://drive.google.com/file/d/1Dia31aIQ1V01U0FQBz8YnedrOF6RlRHh/view?usp=sharing


@amusleh

amusleh
23 Apr 2021, 10:21

Hi,

Async functions are none blocking functions, if you call an async function it will not block the current thread and the thread can continue executing next line of code or commands.

Whenever the OnStop code execution is finished the cBot will stop, so to solve this you can either use synchronous methods or use a thread blocking technique like:

using cAlgo.API;
using System.Threading;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Test : Robot
    {
        private bool _stop;

        protected override void OnStart()
        {
        }

        protected override void OnStop()
        {
            Print("On Stop Start");

            var thread = new Thread(() =>
            {
                Thread.Sleep(5000);

                _stop = true;
            });

            thread.Start();

            while (_stop == false)
            {
                Thread.Sleep(1000);
            }

            Print("On Stop Finished");
        }
    }
}

The thread sleep method works fine, on my sample code I block the current thread until the other thread set the "_stop" field value to true after 5 seconds.

You can wait for your async method callbacks the same way.


@amusleh

amusleh
22 Apr 2021, 14:18

If you call the ShowPopup method either it will show the popup or it will show an error message on your indicator/cBot logs if you set the "Logger.Trace" to "Print".

Please post your indicator code and then I will be able to help you.


@amusleh

amusleh
22 Apr 2021, 12:36 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE: RE: RE: RE: RE: RE:

tekASH said:

amusleh said:

tekASH said:

tekASH said:

amusleh said:

tekASH said:

amusleh said:

Hi,

You have to install the library on every indicator/cBot you want to use it on, not on Visual Studio.

The nuget packages are installed on your cBot/indicator projects, so if you created a new one then you have to install it n your new indicator/cBot.

1. mate, look...I clicked Edit the Bot in VS as you explain in Installation...then installed Alert.API (library?) thing from Nuget...after that..I added those small codes in cTrader (Automate) to my existing bot. I built it successfully.
I turn on the Bot pressing Play...it is active but Alerts window is not opening up..where is it. now what?

 

Libraries are in the Bot

 

2. btw, is this correct?

Please do this:

0. Create a new indicator

1. Install Alert library on it via Nuget

2. After that re-build your indicator from Visual Studio, not from cTrader automate, Right click on your solution name select Rebuild

3. Then copy the sample indicator code and paste it on your new indicator code file, rebuild

4. Attach it on a one minute chart, wait for indicator show popup condition to meet, and you will see the popup will appear

If it still doesn't work, post your full indicator code here.

mate, I somehow managed to generate that Aler window with Settings. Enabled Sound Alert too. But no pop-up come up when entry/exit is trigged. (Havent configured Email or Telegram yet).

I added these too:

Notifications.ShowPopup()
using cAlgo.API.Alert;

still no pop-up...

I also added Telegram bot..it is added proeprly. But no alerts is sent to Telegram.

After you configured the Telegram alert, whenever you call ShowPopup with an alert it will trigger the Telegram, sound, and email alerts.

Are you sure you are calling the ShowPopup? put a Print call below it so you will know its called.

I describe what I did in previous post and asked if I do it properly?

Is it enough to add this

Notifications.ShowPopup()   or there must be some text inside parentheses?  

I have no coding skills...i intuitively understand things and only follow instructions.

Hi,

No, its not, if you call ShowPopup without passing anything then it will only show the popup window, there is no alert to trigger.

You have to use different overloads of ShowPopup method to pass your alert data, example:

using cAlgo.API;
using cAlgo.API.Alert;
using System;
using cAlgo.API.Alert.Utility;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class AlertTest : Indicator
    {
        private int _barIndex;

        protected override void Initialize()
        {
            // Setting this allows you to see the alert library error messages on the cTrader logs
            // It's optional
            Logger.Tracer = Print;
        }

        public override void Calculate(int index)
        {
            if (_barIndex != index && IsLastBar)
            {
                _barIndex = index;

                TradeType tradeType = MarketSeries.Close[index - 1] > MarketSeries.Open[index - 1] ? TradeType.Buy : TradeType.Sell;

                Notifications.ShowPopup(MarketSeries.TimeFrame, Symbol, tradeType, "AlertTest Indicator", Symbol.Bid, "No comment", Server.Time);
            }
        }
    }
}

You see on above sample indicator code, it passes an alert to show popup, the alert data is the time frame, symbol, trade type, triggered by who, price, and some extra comment.

Please check other overloads of the ShowPopup method too with Visual Studio.


@amusleh

amusleh
22 Apr 2021, 10:07 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE: RE: RE: RE:

tekASH said:

tekASH said:

amusleh said:

tekASH said:

amusleh said:

Hi,

You have to install the library on every indicator/cBot you want to use it on, not on Visual Studio.

The nuget packages are installed on your cBot/indicator projects, so if you created a new one then you have to install it n your new indicator/cBot.

1. mate, look...I clicked Edit the Bot in VS as you explain in Installation...then installed Alert.API (library?) thing from Nuget...after that..I added those small codes in cTrader (Automate) to my existing bot. I built it successfully.
I turn on the Bot pressing Play...it is active but Alerts window is not opening up..where is it. now what?

 

Libraries are in the Bot

 

2. btw, is this correct?

Please do this:

0. Create a new indicator

1. Install Alert library on it via Nuget

2. After that re-build your indicator from Visual Studio, not from cTrader automate, Right click on your solution name select Rebuild

3. Then copy the sample indicator code and paste it on your new indicator code file, rebuild

4. Attach it on a one minute chart, wait for indicator show popup condition to meet, and you will see the popup will appear

If it still doesn't work, post your full indicator code here.

mate, I somehow managed to generate that Aler window with Settings. Enabled Sound Alert too. But no pop-up come up when entry/exit is trigged. (Havent configured Email or Telegram yet).

I added these too:

Notifications.ShowPopup()
using cAlgo.API.Alert;

still no pop-up...

I also added Telegram bot..it is added proeprly. But no alerts is sent to Telegram.

After you configured the Telegram alert, whenever you call ShowPopup with an alert it will trigger the Telegram, sound, and email alerts.

Are you sure you are calling the ShowPopup? put a Print call below it so you will know its called.


@amusleh

amusleh
22 Apr 2021, 10:04

Hi,

You can call Bars.OpenTimes.GetindexByTime two times with two indices, for example you call it first with index 5 and then 6, and it returns 10 for the first call and 20 for the second call, then you know from 10 to 20 belongs to first index.


@amusleh

amusleh
22 Apr 2021, 09:23

Hi,

Indices are not fixed, they can change, instead use bar open times.

If you want to get index of a bar on a different time frame you can use GetIndexByTime method of Bars.OpenTimes, check this sample indicator code:

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

namespace cAlgo
{
    [Cloud("Top", "Bottom", Opacity = 0.2)]
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class BollingerBandsMTFCloudSample : Indicator
    {
        private BollingerBands _bollingerBands;

        private Bars _baseBars;

        [Parameter("Base TimeFrame", DefaultValue = "Daily")]
        public TimeFrame BaseTimeFrame { get; set; }

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

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

        [Parameter("Standard Deviation", DefaultValue = 2, MinValue = 0)]
        public double StandardDeviation { get; set; }

        [Parameter("MA Type", DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MaType { get; set; }

        [Output("Main", LineColor = "Yellow", PlotType = PlotType.Line, Thickness = 1)]
        public IndicatorDataSeries Main { get; set; }

        [Output("Top", LineColor = "Red", PlotType = PlotType.Line, Thickness = 1)]
        public IndicatorDataSeries Top { get; set; }

        [Output("Bottom", LineColor = "Red", PlotType = PlotType.Line, Thickness = 1)]
        public IndicatorDataSeries Bottom { get; set; }

        protected override void Initialize()
        {
            _baseBars = MarketData.GetBars(BaseTimeFrame);

            var baseSeries = GetBaseSeries();

            _bollingerBands = Indicators.BollingerBands(baseSeries, Periods, StandardDeviation, MaType);
        }

        public override void Calculate(int index)
        {
            var baseIndex = _baseBars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);

            Main[index] = _bollingerBands.Main[baseIndex];
            Top[index] = _bollingerBands.Top[baseIndex];
            Bottom[index] = _bollingerBands.Bottom[baseIndex];
        }

        private DataSeries GetBaseSeries()
        {
            switch (DataSeriesType)
            {
                case DataSeriesType.Open:
                    return _baseBars.OpenPrices;

                case DataSeriesType.High:
                    return _baseBars.HighPrices;

                case DataSeriesType.Low:
                    return _baseBars.LowPrices;

                case DataSeriesType.Close:
                    return _baseBars.ClosePrices;
                default:

                    throw new ArgumentOutOfRangeException("DataSeriesType");
            }
        }
    }

    public enum DataSeriesType
    {
        Open,
        High,
        Low,
        Close
    }
}

 


@amusleh

amusleh
21 Apr 2021, 13:51

Hi,

You can post a job request, or contact one of our consultants for developing your cBot.


@amusleh

amusleh
21 Apr 2021, 13:50

RE: RE:

mcho911 said:

HI @amusleh,

Thank you for this detailed sample. It makes much more sense to how to do it properly. It seems to work at first. However, it cancel the StopLimit Order when price hit instead of triggering the order. 

It's strange that it catch the error to stop the cbot but wouldn't print the error to the console. Any solution? 

 

 

Hi,

What do you mean? I just tried two buy and sell stop limit orders with opposite trigger method and it got triggered without any problem.


@amusleh

amusleh
21 Apr 2021, 08:40

Hi,

It works fine, try this sample:

using cAlgo.API;
using System;
using System.Globalization;

namespace cAlgo.Robots
{
    /// <summary>
    /// This sample bot shows how to place different types of pending orders
    /// </summary>
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class PendingOrderPlacingSample : Robot
    {
        [Parameter("Type", DefaultValue = PendingOrderType.Limit)]
        public PendingOrderType OrderType { get; set; }

        [Parameter("Direction", DefaultValue = TradeType.Buy)]
        public TradeType OrderTradeType { get; set; }

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

        [Parameter("Distance (Pips)", DefaultValue = 20, MinValue = 1)]
        public double DistanceInPips { get; set; }

        [Parameter("Stop (Pips)", DefaultValue = 10, MinValue = 0)]
        public double StopInPips { get; set; }

        [Parameter("Target (Pips)", DefaultValue = 10, MinValue = 0)]
        public double TargetInPips { get; set; }

        [Parameter("Limit Range (Pips)", DefaultValue = 10, MinValue = 1)]
        public double LimitRangeInPips { get; set; }

        [Parameter("Expiry", DefaultValue = "00:00:00")]
        public string Expiry { get; set; }

        [Parameter("Label")]
        public string Label { get; set; }

        [Parameter("Comment")]
        public string Comment { get; set; }

        [Parameter("Trailing Stop", DefaultValue = false)]
        public bool HasTrailingStop { get; set; }

        [Parameter("Stop Loss Method", DefaultValue = StopTriggerMethod.Trade)]
        public StopTriggerMethod StopLossTriggerMethod { get; set; }

        [Parameter("Stop Order Method", DefaultValue = StopTriggerMethod.Trade)]
        public StopTriggerMethod StopOrderTriggerMethod { get; set; }

        [Parameter("Async", DefaultValue = false)]
        public bool IsAsync { get; set; }

        protected override void OnStart()
        {
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);

            DistanceInPips *= Symbol.PipSize;

            var stopLoss = StopInPips == 0 ? null : (double?)StopInPips;
            var takeProfit = TargetInPips == 0 ? null : (double?)TargetInPips;

            TimeSpan expiry;

            if (!TimeSpan.TryParse(Expiry, CultureInfo.InvariantCulture, out expiry))
            {
                Print("Invalid expiry");

                Stop();
            }

            var expiryTime = expiry != TimeSpan.FromSeconds(0) ? (DateTime?)Server.Time.Add(expiry) : null;

            TradeResult result = null;

            switch (OrderType)
            {
                case PendingOrderType.Limit:
                    var limitPrice = OrderTradeType == TradeType.Buy ? Symbol.Ask - DistanceInPips : Symbol.Ask + DistanceInPips;

                    if (IsAsync)
                        PlaceLimitOrderAsync(OrderTradeType, SymbolName, volumeInUnits, limitPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, OnCompleted);
                    else
                        result = PlaceLimitOrder(OrderTradeType, SymbolName, volumeInUnits, limitPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod);

                    break;

                case PendingOrderType.Stop:
                    var stopPrice = OrderTradeType == TradeType.Buy ? Symbol.Ask + DistanceInPips : Symbol.Ask - DistanceInPips;

                    if (IsAsync)
                        PlaceStopOrderAsync(OrderTradeType, SymbolName, volumeInUnits, stopPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod, OnCompleted);
                    else
                        result = PlaceStopOrder(OrderTradeType, SymbolName, volumeInUnits, stopPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod);

                    break;

                case PendingOrderType.StopLimit:
                    var stopLimitPrice = OrderTradeType == TradeType.Buy ? Symbol.Ask + DistanceInPips : Symbol.Ask - DistanceInPips;

                    if (IsAsync)
                        PlaceStopLimitOrderAsync(OrderTradeType, SymbolName, volumeInUnits, stopLimitPrice, LimitRangeInPips, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod, OnCompleted);
                    else
                        result = PlaceStopLimitOrder(OrderTradeType, SymbolName, volumeInUnits, stopLimitPrice, LimitRangeInPips, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod);

                    break;

                default:
                    Print("Invalid order type");

                    throw new ArgumentOutOfRangeException("OrderType");
            }

            if (!IsAsync) OnCompleted(result);
        }

        private void OnCompleted(TradeResult result)
        {
            if (!result.IsSuccessful) Print("Error: ", result.Error);

            Stop();
        }
    }
}

There is two stop trigger method parameters, one for stop loss order and another for stop order itself.


@amusleh

amusleh
21 Apr 2021, 08:30 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE:

tekASH said:

amusleh said:

Hi,

You have to install the library on every indicator/cBot you want to use it on, not on Visual Studio.

The nuget packages are installed on your cBot/indicator projects, so if you created a new one then you have to install it n your new indicator/cBot.

1. mate, look...I clicked Edit the Bot in VS as you explain in Installation...then installed Alert.API (library?) thing from Nuget...after that..I added those small codes in cTrader (Automate) to my existing bot. I built it successfully.
I turn on the Bot pressing Play...it is active but Alerts window is not opening up..where is it. now what?

 

Libraries are in the Bot

 

2. btw, is this correct?

Please do this:

0. Create a new indicator

1. Install Alert library on it via Nuget

2. After that re-build your indicator from Visual Studio, not from cTrader automate, Right click on your solution name select Rebuild

3. Then copy the sample indicator code and paste it on your new indicator code file, rebuild

4. Attach it on a one minute chart, wait for indicator show popup condition to meet, and you will see the popup will appear

If it still doesn't work, post your full indicator code here.


@amusleh

amusleh
20 Apr 2021, 18:44

RE: RE:

tekASH said:

amusleh said:

Hi,

You don't have to set the configuration parameters, those are optional.

First you have to install the Alert popup library via Nuget on your indicator/cBot project, the installation tutorial is on Github Wiki.

Once you installed you have to add the "using cAlgo.API.Alert" on top of your indicator/cBot code file, then you will be able to call the "ShowPopup".

If you read the Wiki you will find the answer for your questions.

so...I did Installation steps again..then added "using cAlgo.API.Alert" then added Notifications.ShowPopup(); it did build it successfully...but now after turning on the Bot...that Settings window of Alerts doesnt show up? Does it need to show up or where I access it? Cause I need to configure Telegram alerts.

Hi,

To open settings click on "Settings" icon at the title bar of Alert popup window.


@amusleh