Topics
02 Aug 2024, 08:40
 330
 8
14 Jul 2024, 19:24
 1
 280
 0
10 Jul 2024, 20:06
 1
 282
 0
14 Jun 2024, 20:33
 306
 2
Replies

ncel01
05 Jul 2022, 19:58

RE:

PanagiotisCharalampous said:

Hi ncel01,

Can you provide us  with a cBot that will allow us to reproduce what you are looking at?

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

Hi Panagiotis,

Thanks for your reply.
Below is an example that can be used to check this. Margin is calculated once the position opens and then compared to Account.Margin.

using System;
using cAlgo.API;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Margincalc : Robot
    {
        [Parameter(DefaultValue = 0.0, Step = 0.1)]
        public double VolumeInUnits { get; set; }

        protected override void OnStart()
        {
            Positions.Opened += Positions_Opened;
            ExecuteMarketOrder(TradeType.Buy, Symbol.Name, VolumeInUnits);
        }

        private void Positions_Opened(PositionOpenedEventArgs obj)
        {
            var leverageMin = Math.Min(Account.PreciseLeverage, Symbol.DynamicLeverage[0].Leverage);
            var accountMargin = obj.Position.VolumeInUnits * obj.Position.EntryPrice / leverageMin;

            Print("Volume in units : ", obj.Position.VolumeInUnits);
            Print("Entry price : ", obj.Position.EntryPrice);
            Print("Min. applicable leverage : ", leverageMin);
            Print("Account margin (calculated) : {0:0.00}", accountMargin);
            Print("Account.Margin (API): ", Account.Margin);
        }

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

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

 


@ncel01

ncel01
24 Jun 2022, 10:22

RE:

PanagiotisCharalampous said:

Hi ncel01,

Here is an example for getting the highest price from all the bars loaded on the 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.None)]
    public class NewcBot : Robot
    {
        [Parameter(DefaultValue = "Hello world!")]
        public string Message { get; set; }

        protected override void OnStart()
        {
            // To learn more about cTrader Automate visit our Help Center:
            // https://help.ctrader.com/ctrader-automate

            Print(Bars.HighPrices.Maximum(Bars.HighPrices.Count));
        }

        protected override void OnTick()
        {
            // Handle price updates here
        }

        protected override void OnStop()
        {
            // Handle cBot stop here
        }
    }
}

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

Hi Panagiotis,

That's clear. Thanks!


@ncel01

ncel01
18 May 2022, 13:20

RE: RE: RE:

amusleh said:

ncel01 said:

amusleh said:

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.

Hi amusleh,

Thanks for your reply. It's working now! ????

One more question:

Is there a way to filter out from History collection the partial close trades only?

Thank you!

Hi,

No, you can't filter historical trades by type of their close.

amusleh,

Okay, no worries. I'll create a counter for this inside Positions_Modified.


@ncel01

ncel01
18 May 2022, 13:18

RE:

amusleh said:

Hi,

Server.Time and Server.TimeInUtc give you the back test time.

Hi amusleh,

Great. Thanks for informing!


@ncel01

ncel01
16 May 2022, 20:13

RE:

amusleh said:

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.

Hi amusleh,

Thanks for your reply. It's working now! ????

One more question:

Is there a way to filter out from History collection the partial close trades only?

Thank you!


@ncel01

ncel01
27 Apr 2022, 13:40

RE:

amusleh said:

Hi,

The code I posted does the same thing but without suspending the thread of causing any delay, that's the fastest possible solution.

Regarding time delay, no there no such function in API and I don't think there is a need for something like that.

Hi amusleh,

It sounds good. Many thanks!

Regarding the time delay, I asked to be aware if this was considered when backtesting.

If that's not the case, any possible issues due to Async execution can only be noticed when running cBot in real time I am afraid.


@ncel01

ncel01
26 Apr 2022, 14:46

RE:

amusleh said:

Hi,

When using Async calls the main idea is to avoid blocking or suspending the thread, so you call the order place/cancel method and instead of waiting for response you can continue using the thread until the response come back for your requests, so you shouldn't block the thread at all.

Regarding your issue, there are several solutions, when it comes to async programming you can use callbacks like this:

using System.Linq;
using cAlgo.API;
using System.Threading;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Sample : Robot
    {
        private int _numberOfPendingPlaceOrderOperations;
        private int _numberOfPendingCancelOrderOperations;

        protected override void OnStart()
        {
            SetTradesAsync();
        }

        private void SetTradesAsync()
        {
            var amountOfOrders = 20;

            for (int i = 0; i < amountOfOrders; i++)
            {
                Interlocked.Increment(ref _numberOfPendingPlaceOrderOperations);

                PlaceLimitOrderAsync(TradeType.Buy, SymbolName, Symbol.VolumeInUnitsMin, Symbol.Ask - (Symbol.PipSize * 50), "Trade_" + i, OnOrderPlaced);
            }
        }

        private void OnOrderPlaced(TradeResult result)
        {
            Interlocked.Decrement(ref _numberOfPendingPlaceOrderOperations);

            if (Interlocked.CompareExchange(ref _numberOfPendingPlaceOrderOperations, 0, 0) == 0)
            {
                Print("All orders have been created");

                CancelAllPendingOrdersAsync();
            }
        }

        private void CancelAllPendingOrdersAsync()
        {
            var myPendingOrders = PendingOrders.Where(o => o.Label.Contains("Trade_")).ToArray();

            foreach (var order in myPendingOrders)
            {
                Interlocked.Increment(ref _numberOfPendingCancelOrderOperations);

                CancelPendingOrderAsync(order, OnOrderCancel);
            }
        }

        private void OnOrderCancel(TradeResult result)
        {
            Interlocked.Decrement(ref _numberOfPendingCancelOrderOperations);

            if (Interlocked.CompareExchange(ref _numberOfPendingCancelOrderOperations, 0, 0) == 0)
            {
                Print("All orders have been canceled");

                Stop();
            }
        }
    }
}

The better approach would be to use .NET async/await from Task parallel library but unfortunately cTrader automate API is not supporting them for now so you have to use the old callbacks pattern.

Hi amusleh,

Thanks for your reply. 

I want to suspend the thread only to control the execution. However, rather than executing multiple Sync instructions (waiting for all to be processed, one by one), my goal is to execute Async methods and only wait for the latest instruction to be executed, so that execution time can be made as short as possible, since it won't be depending on the amount of instructions (orders created/cancelled). 

Is this the code behavior, when using the OnOrderPlaced() and OnOrderCancel() methods as arguments in the Async methods, as shown above?

Is there a time delay, used to simulate the server time response, considered in backtesting?

Thank you once again!

 

 


@ncel01

ncel01
24 Apr 2022, 23:17

RE: RE: RE: RE: RE:

prosteel1 said:

I use PendingOrders.Count and haven't seen an issue in use, it does seem to be updated as soon as an order is placed which seems to get around the delay between when an order is placed and when it is filled. Here is a roughly cropped example which you should be able to paste into your bot: If you can break it I'll be interested ;) But I think this was the solution to preventing multiple orders for me.

So regardless of code execution sequence semantics, if the point is to prevent multiple orders I believe this works because PendingOrders.Count gets updated immediately upon the placing of an order ;)

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 NewcBot6
{
    [Robot(AccessRights = AccessRights.None)]
    public class NewcBot6 : Robot
    {
        int LongTradeActive = 0;
        int ShortTradeActive = 0;

        protected override void OnStart()
        {
            Print("OnStart");
            Positions.Opened += PositionsOnOpened;
            Positions.Closed += PositionsOnClosed;
        }

        protected override void OnTick()
        {
            // Handle price updates here
            Print("OnTick");
            SetTrade();
        }

        protected override void OnStop()
        {
            // Handle cBot stop here
            Print("OnStop");
        }

        private void SetTrade()
        {
            Print("SetTrade");
            int Longpendingorders = 0;
            int Shortpendingorders = 0;
            var LabelLong = "Long";
            var LabelShort = "Short";

            if (PendingOrders.Count(x => x.Label == LabelLong) > 0)
            {
                foreach (var order in PendingOrders)
                {
                    if (order.SymbolName == SymbolName)
                        Longpendingorders = 1;
                }
            }
            if (PendingOrders.Count(x => x.Label == LabelShort) > 0)
            {
                foreach (var order in PendingOrders)
                {
                    if (order.SymbolName == SymbolName)
                        Shortpendingorders = 1;
                }
            }

            if (LongTradeActive == 0 && Longpendingorders == 0 && Positions.Find(LabelLong, SymbolName) == null && Positions.Find(LabelShort, SymbolName) == null)
            {
                ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000, LabelLong);
            }
            
            if (ShortTradeActive == 0 && Shortpendingorders == 0 && Positions.Find(LabelLong, SymbolName) == null && Positions.Find(LabelShort, SymbolName) == null)
            {
                ExecuteMarketOrder(TradeType.Sell, SymbolName, 1000, LabelShort);
            }

        }

        private void PositionsOnOpened(PositionOpenedEventArgs args)
        {
            Print("PositionsOnOpened");
            var pos = args.Position;
            if (pos.SymbolName == SymbolName)
            {
                if (pos.Label == "Long")
                {
                    LongTradeActive = 1;
                }
                if (pos.Label == "Short")
                {
                    ShortTradeActive = 1;
                }
            }
        }

        private void PositionsOnClosed(PositionClosedEventArgs args)
        {
            Print("PositionsOnClosed");
            var pos = args.Position;
            if (pos.SymbolName == SymbolName)
            {
                if (pos.Label == "Long")
                {
                    LongTradeActive = 0;
                }
                if (pos.Label == "Short")
                {
                    ShortTradeActive = 0;
                }
            }
        }
    }
}

 

Hi prosteel1,

Thanks for your reply but I've already found the issue!
I was changing a variable inside PendingOrders_Created() event, reason why another order was being created.
I am still trying to handle some residual issues associated to Async mode. Since my strategy involves a high amount of orders, using Sync mode won't be efficient at all, however, on the other hand, Async mode is not so intuitive nor it is as easy to manage.


@ncel01

ncel01
19 Apr 2022, 14:42

RE: RE: RE:

amusleh said:

ncel01 said:

amusleh said:

Hi,

Try this:

using cAlgo.API;
using System.Linq;
using System.Threading;

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

        protected override void OnStart()
        {
            var tradeResults = SetTrade();

            Print("Closing Positions");

            foreach (var tradeResult in tradeResults)
            {
                ClosePosition(tradeResult.Position);
            }

            allPositionsClosed = true;

            Print("All positions closed: ", allPositionsClosed);

            Stop();
        }

        private TradeResult[] SetTrade()
        {
            var tradeResults = new TradeResult[3];

            tradeResults[0] = ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.QuantityToVolumeInUnits(0.01), "order_1");
            tradeResults[1] = ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.QuantityToVolumeInUnits(0.01), "order_2");
            tradeResults[2] = ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.QuantityToVolumeInUnits(0.01), "order_3");

            while (tradeResults.Any(result => result.Position is null))
            {
                Thread.Sleep(100);

                RefreshData();
            }

            return tradeResults;
        }

        protected override void OnStop()
        {
        }
    }
}

 

Hi amusleh,

I am afraid that creating time delays will not solve the issue as there are dozens/hundreds of orders involved and this wouldn't be an efficient/effective solution at all, I believe.

Because either the Positions collection is not updated yet (in my case), it gets updated after the thread is released from the execution of an event (OnStart. OnBar, OnTick, etc...) or even if it's updated (based on your output) the close position request can't suspend the current execution and jump to executing the event handlers (here Positions_Closed).

What can be a reason for such limitation? Wouldn't be possible that these follow the code sequence, as it happens for user-defined methods?

I am sure this would be much more intuitive and, as result, the outcome a lot more effective. Looks to me that managing a high amount of orders/positions seems to be quite hard (if not impossible) considering that internal (API) methods/functions execute asynchronously with respect to the code sequence.

Is there available any diagram (or similar) illustrating how execution is processed through cTrader API functions/methods? I believe this particularity is not really a detail when it comes to creating any "reliable" (behaving as expected) cBot/strategy. Maybe I can get to a solution if I am fully aware of how this really works. So far, it looks like I've been on a loop trying to get this solved.

Does this characteristic/limitation only apply to the events or, to any method? Only to methods?

Another question:  PendingOrders_Created() and PlaceStopOrderAsync(). Do these methods always get triggered simultaneously (as a pair) or, can be that some code is still executed in between?

On my last attempt, I've added PendingOrders_Created() event. The goal was only to modify the value of a variable inside the event. However, soon I noticed that, unlike for a single order, the amount of orders keeps increasing whenever the "real" order is placed. A "clone" order is created, which does not happen if only a single order is initially defined. I also don't know why this is happening nor I do know how to solve this.

My strategy has 2000+ code lines and it is almost finished (I would say). So far, I've been able to solve every issue I noticed but not this one. The only issue, still remaining, is in fact, related to the loop ( pending order placed --> pending order filled --> position closed --> pending order placed ... ), which is still not working as expected, after many tries.

Thank you once again!

Hi,

There is no way to prevent waiting, Automate API is an abstraction over sending and receiving messages to cTrader server, if you have done any kind of network programming you know that when you send something to server/client you have to wait to get back a response, when you send a request from Automate API you have to wait to get back the response from server, there we use the Thread.Sleep method to wait until we receive response for all of our order requests from server.

Regarding your other points, all operations on a cBot is executed by a single thread, and a single thread can execute a single line of code at the time.

If you understand how a single thread environment works you will be able to understand how cTrader automate executes your code.

cTrader automate executes your cBot overloaded methods and event handlers one by one, if the thread is inside OnTick method and a position is closed it can't suspend OnTick method execution and jump to your Position closed event handler, first it finish the execution of OnTick method then it executes your position closed event handler, the same is true for all other methods, event handlers, and collections (Positions and PendingOrders).

When you send something to server you have to wait to get back the response, you can't expect the response to be available instantly, if you sent a market order request you can't expect Positions collections to have your market order position immediately.

A better approach for you to control the sequence of execution will be used the Async calls with callbacks, the async method callbacks will be called when a response is received from server, and while waiting for server response you can execute some other code instead of suspending the thread and waiting for a server response.

Hi amusleh,

Yes, I am aware that there's always a time delay when waiting for a response from the server, that's why I provided an example of synchronous execution ClosePosition(), which in fact I thought, would suspend all the executions of the remaining code.

Nevertheless, and as suggested, I'll implement the callbacks and hope these will solve my problem!

On my last attempt, I've added PendingOrders_Created() event. The goal was only to modify the value of a variable inside the event. However, soon I noticed that, unlike for a single order, the amount of orders keeps increasing whenever the "real" order is placed. A "clone" order is created, which does not happen if only a single order is initially defined. I also don't know why this is happening nor I do know how to solve this.

This seems to be related to the event subscription PendingOrders.Created += PendingOrders_Created, however, it won't work, at all, without this.
How can I make this event "code neutral" without affecting any of the cBot outcome? For instance, if I only want to execute a Print() inside the event?

 

Thank you!


@ncel01

ncel01
19 Apr 2022, 00:02

RE:

amusleh said:

Hi,

Try this:

using cAlgo.API;
using System.Linq;
using System.Threading;

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

        protected override void OnStart()
        {
            var tradeResults = SetTrade();

            Print("Closing Positions");

            foreach (var tradeResult in tradeResults)
            {
                ClosePosition(tradeResult.Position);
            }

            allPositionsClosed = true;

            Print("All positions closed: ", allPositionsClosed);

            Stop();
        }

        private TradeResult[] SetTrade()
        {
            var tradeResults = new TradeResult[3];

            tradeResults[0] = ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.QuantityToVolumeInUnits(0.01), "order_1");
            tradeResults[1] = ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.QuantityToVolumeInUnits(0.01), "order_2");
            tradeResults[2] = ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.QuantityToVolumeInUnits(0.01), "order_3");

            while (tradeResults.Any(result => result.Position is null))
            {
                Thread.Sleep(100);

                RefreshData();
            }

            return tradeResults;
        }

        protected override void OnStop()
        {
        }
    }
}

 

Hi amusleh,

I am afraid that creating time delays will not solve the issue as there are dozens/hundreds of orders involved and this wouldn't be an efficient/effective solution at all, I believe.

Because either the Positions collection is not updated yet (in my case), it gets updated after the thread is released from the execution of an event (OnStart. OnBar, OnTick, etc...) or even if it's updated (based on your output) the close position request can't suspend the current execution and jump to executing the event handlers (here Positions_Closed).

What can be a reason for such limitation? Wouldn't be possible that these follow the code sequence, as it happens for user-defined methods?

I am sure this would be much more intuitive and, as result, the outcome a lot more effective. Looks to me that managing a high amount of orders/positions seems to be quite hard (if not impossible) considering that internal (API) methods/functions execute asynchronously with respect to the code sequence.

Is there available any diagram (or similar) illustrating how execution is processed through cTrader API functions/methods? I believe this particularity is not really a detail when it comes to creating any "reliable" (behaving as expected) cBot/strategy. Maybe I can get to a solution if I am fully aware of how this really works. So far, it looks like I've been on a loop trying to get this solved.

Does this characteristic/limitation only apply to the events or, to any method? Only to methods?

Another question:  PendingOrders_Created() and PlaceStopOrderAsync(). Do these methods always get triggered simultaneously (as a pair) or, can be that some code is still executed in between?

On my last attempt, I've added PendingOrders_Created() event. The goal was only to modify the value of a variable inside the event. However, soon I noticed that, unlike for a single order, the amount of orders keeps increasing whenever the "real" order is placed. A "clone" order is created, which does not happen if only a single order is initially defined. I also don't know why this is happening nor I do know how to solve this.

My strategy has 2000+ code lines and it is almost finished (I would say). So far, I've been able to solve every issue I noticed but not this one. The only issue, still remaining, is in fact, related to the loop ( pending order placed --> pending order filled --> position closed --> pending order placed ... ), which is still not working as expected, after many tries.

Thank you once again!


@ncel01

ncel01
15 Apr 2022, 14:39 ( Updated at: 21 Dec 2023, 09:22 )

RE:

amusleh said:

Hi,

cTrader cBots/Indicators run on a single thread and their code indeed are executed sequentially.

Regarding your code, this is the result I got:

15/04/2022 13:10:42.947 | CBot instance [New cBot, EURUSD, h1] started.
15/04/2022 13:10:43.650 | Stage #1
15/04/2022 13:10:44.134 | Stage #2
15/04/2022 13:10:44.556 | Stage #5
15/04/2022 13:10:44.556 | Stage #4
15/04/2022 13:10:44.588 | CBot instance [New cBot, EURUSD, h1] stopped.

The Stage #1 gets printed because it's the first line to be executed inside SetTrade method, all good for now.

The Stage #2 is printed as it's the next line after Stack execution pointer returns from SetMethod.

Next is the loop for closing positions, it iterates over Positions collection and then sends a Close request for each of the positions, then why "Stage #3" is not printed?

Because either the Positions collection is not updated yet (in my case), it gets updated after the thread is released from the execution of an event (OnStart. OnBar, OnTick, etc...) or even if it's updated (based on your output) the close position request can't suspend the current execution and jump to executing the event handlers (here Positions_Closed).

It waits for thread to become free and then it executes the event handler of Positions.Closed event, that's what happened on your case.

Same thing is happening for Stop call, when you call the Stop method it can't suspend the execution of OnStart method and jump to execution of OnStop, instead it first finish the OnStart method and then it executes the OnStop and Positions closed event handler.

As I said each cBot/Indicator runs on a single thread, the thread can only execute one event per time, if you are inside OnTick it can't execute OnBar code or if you are inside OnStart it can't execute the code inside OnStop even if you call it from OnStart, it first finish the current event call and then the next one.

cTrader Automate uses event loop, and it calls each event sequentially when they arrive, only a single event is executed at a time.

Hello amusleh,

Thank you for your reply!

I think that's clear, however, I believe it makes things much more difficult when it comes to controlling execution.

Example:

In the code below, I want to confirm if all the orders have been closed, by using the control variable allPositionsClosed, however, this will never work since allPositionsClosed = true will always proceed Positions_Closed event execution, as you have already explained.

My question is, what can be done so that it is indeed possible to make use of control variables effectively in such cases?

Defining allPositionsClosed = true inside Positions_Closed event could be, maybe, an alternative, however, this will happen once the first position is closed and not the last one. And, in my case, I only want to pass a new value to the control variable after the last event is executed.
Should I create an array, where each index is assigned a value based on the respective closed position, and then assign a value to the main variable based on this data?
I think this can be a solution, however, maybe there is a better/easier way to get this done and I would really like to be aware of it.

Thank you once again!

 

using cAlgo.API;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {

        private bool allPositionsClosed = false;

        protected override void OnStart()
        {

            Positions.Closed += Positions_Closed;

            SetTrade();

            Print("All positions closed: ", allPositionsClosed);

            foreach (var position in Positions)
            {
                ClosePosition(position);
                position.Close();
            }

            allPositionsClosed = true;
            Print("All positions closed: ", allPositionsClosed);

            Stop();
        }

        private void SetTrade()
        {
            ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.QuantityToVolumeInUnits(0.01), "order_1");
            ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.QuantityToVolumeInUnits(0.01), "order_2");
            ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.QuantityToVolumeInUnits(0.01), "order_3");
        }

        private void Positions_Closed(PositionClosedEventArgs obj)
        {
            Print("{0} has been closed", obj.Position.Label);
        }

        protected override void OnStop()
        {
        }

    }
}

 


@ncel01

ncel01
23 Mar 2022, 11:08

RE:

PanagiotisCharalampous said:

Hi ncel01,

Unfortunately I do not read Portuguese (If my guess is correct). But yet, it could be a memory issue as well. If your cBots consume too much memory, this could happen.

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

Hi Panagiotis,

 

Yes, you are correct!

This is the following error: A new guard page for the stack cannot be created.

That's what I thought in fact, a memory issue.

Thanks for your the support once again!

 

Regards


@ncel01

ncel01
22 Mar 2022, 23:21 ( Updated at: 21 Dec 2023, 09:22 )

RE:

PanagiotisCharalampous said:

Hi ncel01,

This should not cause cTrader to close. Maybe some fatal flaw inside the cBot code. We need troubleshooting info to determine what is wrong.

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

Hi Panagiotis,

Thanks for the further clarifications.

In the meantime, I got (for the first time) the following system error message:

A new guard page for the stack cannot be created.

As far as I've read, this can be related to a lack of available RAM at some moment.

Has this been already reported before?

Are you aware of the reason for such an error?

 

Thank you once again!

 


@ncel01

ncel01
22 Mar 2022, 11:52

RE:

PanagiotisCharalampous said:

Hi ncel01,

We do not control the code inside the cBots and this code can cause any side effects, since it is executed on the same process as cTrader. In future releases, cBot and Indicator code will be executed in a separate process, isolating the main process from such effects. Until then, you should be carefull regarding what you are executing on your cTrader platform.

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

Panagiotis,

I understand.

Apparently I don't see why this can happen, apart from an overwhelming use of hardware resources.

Can this be a good reason, maybe?

 

Thank you.


@ncel01

ncel01
22 Mar 2022, 11:30

RE:

PanagiotisCharalampous said:

Hi ncel01,

On the contrary, I believe that would be the reason. If this happens without the cBots running, please send us some troubleshooting information. To do so, press Ctrl+Alt+Shift+T when in cTrader, paste a link to this discussion inside the text box that will appear and then Submit.

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

Hi Panagiotis,

Still, if this only happens when running cBots, it was not supposed to, I believe?


@ncel01

ncel01
02 Mar 2022, 16:39

RE:

PanagiotisCharalampous said:

Hi ncel01,

There is nothing you can do about it besides warning your followers. If somebody decides to follow you from a broker that has different trading conditions than yours, then the only thing we can assume is that he does it consciously in full awareness of what he is doing. We cannot decide not to trade on his behalf. 

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

Panagiotis,

Please consider the possibility for the provider to define a set of requirements or, alternatively, a volume ratio < 0.5 that will reflect a 0 volume on investors' side and not the min. applicable volume.

This would be a good improvement and would definitely solve the issue.

 

Thanks.


@ncel01

ncel01
02 Mar 2022, 16:22

RE:

PanagiotisCharalampous said:

Hi ncel01,

Question

Is the minimum quantity of 1.0 still applicable on the investor side, in case the calculated volume < 0.500 or, is this considered a 0 volume and no orders/positions will take place?

Answer

The minimum quantity will be considered i.e. 1.

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

Hi Panagiotis,

Thanks for your reply.

That will have a terrible effect on investors' margin since min. Investment amount is mainly based on volume min./step. Investors' account will certainly "blow up" when considering 100x or even 10x providers' volume .

I believe that there is here a concerning breach to the equity-to-equity ratio methodology.

How to prevent/mitigate such situation?

I am not really willing to provide brokers with "easy money" by sacrificing investors' accounts.

Is it possible, for instance, to define a set of requirements that investors must comply with, to be able to follow a certain strategy?

I am afraid that mentioning something on strategy description won't be effective, at all, on preventing such cases.

I understand this is maybe not much relevant when trading FX, as almost every broker is following the same min./step volume, however this is not the case for indices.

Thank you once again!


@ncel01

ncel01
01 Mar 2022, 16:20

RE:

ncel01 said:

Hello,

I would like to be aware of the following:
Let's suppose that I publish a strategy, on a given symbol, with a broker which allows a minimum volume of 0.01.

An investor starts copying my strategy, however, his broker only allows a minimum volume of 1.0 on the same instrument.

Based on the equity-to-equity ratio, an investment volume of x < 0.500 is calculated for the investor.


Question: Is the minimum quantity of 1.0 still applicable on the investor side, in case the calculated volume < 0.500 or, is this considered a 0 volume and no orders/positions will take place?

What is the exact way to calculate the investor's final volume, after a volume based on the equity-to-equity ratio is calculated?

  • (1): Calculated volume < 0.500 --> Final volume: Symbol.VolumeInUnitsMin
  • (2): Calculated volume < 0.500 --> Final volume: 0 --> No orders/positions will be paced

If (1) is the applicable scenario, I am afraid it won't be possible to protect investors' money and that, in such cases, their accounts can easily blow up, which can not happen at all!

 

Thank you for clarifying,

Hello,

Could I have a clarification on the above?

Thank you.


@ncel01

ncel01
18 Feb 2022, 12:13

RE: RE: RE: RE:

ncel01 said:

amusleh said:

ncel01 said:

amusleh said:

Hi,

The tick/pip value is constant and it represents the latest tick/Pip value of a symbol when you start the cBot for both real time and back test environments.

 

Hi amusleh,

Yes, indeed. But why doesn't this value keep synchronised with the current forex rate, since it is called OnTick?

When backtesting I can understand but not when running a cBot it in real time, which is a huge limitation.

How to get this value updated in real time for currency conversion purposes, as brokers are able to, when symbol and account currencies don't match?

 

Thank you once again!

Hi,

Right now you can't do currency conversion with the amount of data that is available in Automate API.

We don't have any plan to change the current design of Symbol Pip/tick value but you can open a thread on suggestions section for this.

The data you need to convert currency values for now is only available on Open API.

Hi amusleh,

 

Thanks for your reply.

It's a pity that pip/value is only taken when cBot starts. This makes it not so effective as it should be, as I consider an accurate (real time) currency conversion of high importance.

amusleh,

 

I'll try to do something different here, by declaring e.g.: Symbol eur_usd = Symbols.GetSymbol("EURUSD") for the applicable currency pair, and then refer to eur_usd.Ask or eur_usd.Bid, as these seem to work in real time.

Still, I would need to get the info on the applicable symbol currency. Is there a way to get this for a symbol, as it is available for the account (account.Asset.Name)?

 

Thank you once again!


@ncel01

ncel01
18 Feb 2022, 11:57

RE:

firemyst said:

There's at least two easy options:

1) save the values to a data file, and then read the values back in when you restart your bot. You'll probably want to save to an XML or Json file so you have easy parsers available.

2) not the best practice, but you can create static variable collections and reference those. As long as you don't close cTrader, they should be around. However, if you close down cTrader, you'll lose the values in those variables.

 

Hi firemyst,

 

Thanks for the tip!

I'll try to implement option 1.

 

 


@ncel01