Topics
Replies

firemyst
13 Mar 2025, 07:16

You probably have to contact the developer(s). They can build the algo files to include or not include the source code with their distributions. 

 

 


@firemyst

firemyst
12 Mar 2025, 11:59

RE: RE: RE: RE: RE: RE: RE: RE: RE: RE: Help needed with Asynchronous Close of positions

kadronsa said: 

 

Thanks for confirming my suspicions, as I knew I had to introduce some kind of delay after the async command but didn't know how to do it for the cBot. I've resolved this in MQL by “sleeping” a little while but when I replicate it here the sleep command doesn't work the same. I'll try your suggestion of the flag now that I'm sure what to look for. Thanks again.

I posted sample code to help get you started in case you haven't seen it yet. 


@firemyst

firemyst
12 Mar 2025, 11:50

RE: RE: RE: RE: RE: RE: RE: RE: Help needed with Asynchronous Close of positions

Here's sample code you can run which avoids the issue. It's not perfect since I'm not in front of a compiler, but should work:

bool closingPositions;
int positionsClosed = 0;

protected override void OnStart()
{
    ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000);
    ExecuteMarketOrder(TradeType.Sell, SymbolName, 1000);
    ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000);
    ExecuteMarketOrder(TradeType.Sell, SymbolName, 1000);
    ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000);
    ExecuteMarketOrder(TradeType.Sell, SymbolName, 1000);
    closingPositions = false;
    positionsClosed = 0;
}

protected override void OnTick()
{
    if (!closingPositions)
    {
        CheckOpenOrders();
        BasketControl();
    }
}
protected override void OnStop()
{
    CloseAll();
}
protected void CheckOpenOrders()
{
    BuyLots = 0;
    SellLots = 0;
    MyTrades = 0;

    foreach (var position in Positions)
    {
        if (position.SymbolName == Symbol.Name)
        {
            MyTrades++;
            if (position.TradeType == TradeType.Buy)
            {
                BuyLots += position.VolumeInUnits;
            }
            if (position.TradeType == TradeType.Sell)
            {
                SellLots += position.VolumeInUnits;
            }
        }
    }
}

protected void BasketControl()
{
    if (MyTrades > 5)
        CloseAll();
}

protected void CloseAll()
{
    double BookedProfit = 0;
    var positionsCOLLECTED = Positions.ToArray();

    closingPositions = true;
    foreach (var psnsCLTD in positionsCOLLECTED.Where(p => p.SymbolName == SymbolName))
    {
        double ClosedP = psnsCLTD.NetProfit;

        ClosePositionAsync(psnsCLTD, (TradeResult r) =>
        {
            if (r.IsSuccessful)
            {
                BookedProfit += ClosedP;
                positionsClosed += 1;
            }
            else if (!r.IsSuccessful)
                Print(" >> Failed to close Order! Encountered Error - ", r.Error);

            if (positionsClosed == positionsCOLLECTED.Length)
            {
                closingPositions = false;
                positionsClosed = 0;
            }
        }
        );
    }
}

@firemyst

firemyst
12 Mar 2025, 11:40 ( Updated at: 12 Mar 2025, 11:43 )

RE: RE: RE: RE: RE: RE: RE: RE: Help needed with Asynchronous Close of positions

I don't have to try your code. I can see right away you're doing what I said you would be doing, and you shouldn't be doing it. 

You're running code in the OnTick event handler that still access the Positions object while you're in the process of closing the positions async. What makes you think all the positions are going to be closed by the time the next tick comes in?

In your OnTick you call CheckOpenOrders, which loops over the Positions. 

So the code hits that loop, and is iterating over the objects, when suddenly some of the position objects have finally been closed by the server async.  Thus, in the middle of the foreach loop, it expects to have positions it started iterating over, but they are no longer there, hence your errors. 

 

So as I said in a previous response, you need to set a flag to indicate when you are closing positions. while the flag is true, you DO NOT iterate over the foreach loop (and any other part of code) that operates on the “Positions” object. 

When all the positions have been closed async (which could take multiple ticks), then you set the “closingPositions” flag back to false, and now the bot can iterate your code as usual.


@firemyst

firemyst
12 Mar 2025, 06:04

if (Bars.ClosePrices.Last > Your_Position.Pips)

{

   Your_Position.ModifyTrailingStop(true);

}


@firemyst

firemyst
12 Mar 2025, 06:02

No, no idea, especially since you didn't post any screen captures or show what the URL, error, or anything else.


@firemyst

firemyst
12 Mar 2025, 06:01

Duplicate of: 

 

/forum/ctrader-algo/46539/


@firemyst

firemyst
12 Mar 2025, 06:01

Duplicate:

/forum/ctrader-algo/46539/


@firemyst

firemyst
12 Mar 2025, 05:52

RE: RE: RE: RE: RE: RE: Help needed with Asynchronous Close of positions

The same code I provided you doesn't throw “EntityNotFound” errors when I just ran it.

Are you able to modify the sample code I gave you to reproduce the issue?

I use ClosePositionAsync in all my bots and haven't had any problems.


@firemyst

firemyst
12 Mar 2025, 04:01

Grab the countdown timer and drag left so you bring more of the future in as shown:


@firemyst

firemyst
12 Mar 2025, 03:58

Read other threads in this forums about issues with the cloud


@firemyst

firemyst
12 Mar 2025, 03:57

Having 20 bot instances running on my VPS, I've changed charts a gazillion times and not once has a bot ever closed a position when changing a chart. They might stop and restart, but positions certainly aren't closed.

Can you post a video of this behavior?


@firemyst

firemyst
12 Mar 2025, 02:29

RE: RE: RE: RE: Help needed with Asynchronous Close of positions

kadronsa said: 

firemyst said: 

kadronsa said: 

firemyst said: 

Why are you using “LastResult.Error” and not “closeResult.Error” in the “BulkOrderClose” method?

 

No particular reason. I just reused what I had working before trying out Async close. I have however modified the closing code and replaced “lastresult.error” with the following code but the problem still persists:


        protected void CloseMyTrades()
        {
            var positionsCOLLECTED = Positions.ToArray();

            foreach (var psnsCLTD in positionsCOLLECTED.Where(p => p.SymbolName == SymbolName))
            {
                ClosePositionAsync(psnsCLTD, (TradeResult r) =>
                {
                    if (r.IsSuccessful)
                        BookedProfit += psnsCLTD.NetProfit;
                    else if (!r.IsSuccessful)
                        Print(" >> Failed to close " + psnsCLTD.TradeType + " Order! Encountered Error - ", r.Error);
                }
                );
            }
        }

I still get the following in the output after successfully closing all trades:

11-03-2025 06:39:05.624 | Trade | → Closing position PID665350 (Volume: 18) SUCCEEDED
11-03-2025 06:39:05.702 | Trade | → Closing position PID665351 (Volume: 54) SUCCEEDED
11-03-2025 06:39:05.796 | Trade | → Closing position PID665352 (Volume: 90) SUCCEEDED
11-03-2025 06:39:05.889 | Trade | → Closing position PID665353 (Volume: 126) SUCCEEDED
11-03-2025 06:39:05.983 | Trade | → Closing position PID665350 (Volume: 18) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665351 (Volume: 54) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665352 (Volume: 90) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665353 (Volume: 126) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665350 (Volume: 18) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665351 (Volume: 54) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665352 (Volume: 90) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665353 (Volume: 126) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665350 (Volume: 18) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665351 (Volume: 54) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665352 (Volume: 90) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665353 (Volume: 126) FAILED with error "EntityNotFound"

What am I missing?

Thanks.

You're trying to read the profit of a closed position:

 

BookedProfit += psnsCLTD.NetProfit;

How can you read the profit of a position that no longer exists?

Thanks for pointing that out, but it doesn't seem to be the root cause for the error. I've modified code accordingly but still get the “EntityNotFound” errors:

protected void CloseMyTrades()
        {
            var positionsCOLLECTED = Positions.ToArray();

            foreach (var psnsCLTD in positionsCOLLECTED.Where(p => p.SymbolName == SymbolName))
            {
                double ClosedP = psnsCLTD.NetProfit;

                ClosePositionAsync(psnsCLTD, (TradeResult r) =>
                {
                    if (r.IsSuccessful)
                        BookedProfit += ClosedP;
                    else if (!r.IsSuccessful)
                        Print(" >> Failed to close Order! Encountered Error - ", r.Error);
                }
                );
            }
        }

There's nothing wrong with that code as is unless “BookedProfit” isn't a double.

You haven't posted your entire code, so I suspect you have an event listener or something else happening elsewhere. If you want proof of this, create a test bot and just put in the code I have below.

For instance, in your “OnTick” or “OnBar” methods, do you actually check if the position exists before doing anything? 

 

After all, when you tell the system to close the position async, the position might still be open when the next tick comes through, and your bot will then try to perform operations on it. But then the position gets closed halfway through, and it can no longer be found. Closing a position async doesn't guarantee an immediate close, or closure before the method exits.

//create a new bot. And just add these two methods. I bet you'll see your closing code works fine.
protected override void OnStart()
{
    ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000);
    ExecuteMarketOrder(TradeType.Sell, SymbolName, 1000);
}

protected override void OnStop()
{
    double BookedProfit = 0;
    var positionsCOLLECTED = Positions.ToArray();

    foreach (var psnsCLTD in positionsCOLLECTED.Where(p => p.SymbolName == SymbolName))
    {
        double ClosedP = psnsCLTD.NetProfit;

        ClosePositionAsync(psnsCLTD, (TradeResult r) =>
        {
            if (r.IsSuccessful)
                BookedProfit += ClosedP;
            else if (!r.IsSuccessful)
                Print(" >> Failed to close Order! Encountered Error - ", r.Error);
        }
        );
    }
}

//When the above works fine for you too, that's evidence you are still trying to do things elsewhere in code you haven't shared that's operating on positions as you're closing them off.

@firemyst

firemyst
11 Mar 2025, 13:20

RE: RE: Help needed with Asynchronous Close of positions

kadronsa said: 

firemyst said: 

Why are you using “LastResult.Error” and not “closeResult.Error” in the “BulkOrderClose” method?

 

No particular reason. I just reused what I had working before trying out Async close. I have however modified the closing code and replaced “lastresult.error” with the following code but the problem still persists:


        protected void CloseMyTrades()
        {
            var positionsCOLLECTED = Positions.ToArray();

            foreach (var psnsCLTD in positionsCOLLECTED.Where(p => p.SymbolName == SymbolName))
            {
                ClosePositionAsync(psnsCLTD, (TradeResult r) =>
                {
                    if (r.IsSuccessful)
                        BookedProfit += psnsCLTD.NetProfit;
                    else if (!r.IsSuccessful)
                        Print(" >> Failed to close " + psnsCLTD.TradeType + " Order! Encountered Error - ", r.Error);
                }
                );
            }
        }

I still get the following in the output after successfully closing all trades:

11-03-2025 06:39:05.624 | Trade | → Closing position PID665350 (Volume: 18) SUCCEEDED
11-03-2025 06:39:05.702 | Trade | → Closing position PID665351 (Volume: 54) SUCCEEDED
11-03-2025 06:39:05.796 | Trade | → Closing position PID665352 (Volume: 90) SUCCEEDED
11-03-2025 06:39:05.889 | Trade | → Closing position PID665353 (Volume: 126) SUCCEEDED
11-03-2025 06:39:05.983 | Trade | → Closing position PID665350 (Volume: 18) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665351 (Volume: 54) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665352 (Volume: 90) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665353 (Volume: 126) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665350 (Volume: 18) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665351 (Volume: 54) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665352 (Volume: 90) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665353 (Volume: 126) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665350 (Volume: 18) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665351 (Volume: 54) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665352 (Volume: 90) FAILED with error "EntityNotFound"
11-03-2025 06:39:05.983 | Trade | → Closing position PID665353 (Volume: 126) FAILED with error "EntityNotFound"

What am I missing?

Thanks.

You're trying to read the profit of a closed position:

 

BookedProfit += psnsCLTD.NetProfit;

How can you read the profit of a position that no longer exists?


@firemyst

firemyst
11 Mar 2025, 01:31

You have what appears to be quite a few logic errors in your code.

The first is the obvious:

position.ModifyStopLossPips(newStopLossPrice);

You're calling the method that expects “pips” as a parameter, and you're passing in a “price”. 

 

Second is within the loop:

if (distance < TrailingStopTrigger * Symbol.PipSize)
                continue;

 

Do you mean “break;” and not “continue;” ?

If not, what's the point of having the statement since the code logic will allow it to continue anyway regardless if the statement is true or not?


@firemyst

firemyst
11 Mar 2025, 01:24

How can it be taken into account?

Backtesting won't move at the same speed as the markets. In real live environments, you have network issues, server load, and other miscellaneous things that happen that aren't present and/or can't be replicated in backtesting.


@firemyst

firemyst
11 Mar 2025, 01:22

Why are you using “LastResult.Error” and not “closeResult.Error” in the “BulkOrderClose” method?

 


@firemyst

firemyst
11 Mar 2025, 01:15

Have you tried clicking on the date/time column for the cloud logs to see if they can be sorted in ascending or descending order? I don't use the cloud, so I don't know if it's possible, but could be something to try?


@firemyst

firemyst
11 Mar 2025, 01:12

You need to speak to your broker.


@firemyst

firemyst
11 Mar 2025, 00:49

RE: RE: RE: RE: RE: RE: RE: Stop Loss/ Take Profit being set at wrong distance by algo

thanks for sharing your code.

For starters, you have “ExecuteMarketOrder” in 3 places, so you need to put those print statements in the 3 places.

You might want to add a 3rd print statement that indicates which branch of code it's printing. For example:

Print ("Hello from area 1");

Be sure to adjust their output to how you calculate the SL and TP in each location.

For instance, in one place, you have:

Symbol.Bid + TakeProfitInPips * Symbol.PipSize;

and in another:

Symbol.Ask - TakeProfitInPips * Symbol.PipSize;

 


@firemyst