Race conditions/timing issue with backtester when using both Positions.Closed and OnBar

Created at 04 Oct 2020, 00:45
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
keno.clayton15's avatar

keno.clayton15

Joined 04.10.2020

Race conditions/timing issue with backtester when using both Positions.Closed and OnBar
04 Oct 2020, 00:45


This is a tricky one to explain but hopefully I can get my point across clearly.

I'm developing a custom trading bot that starts an initial trade, and performs specific actions when the stop loss is hit. I also have allowed it to execute trades OnBar depending on some criteria that I've set. Now the important thing to note is that only 1 trade can be executed at a time for this bot. To ensure this, I have a bool value that I set to true whenever I am about to execute a new trade, and I set it to false when that trade has been successfully executed. Below you can see a simplified version of how that is done on my end.

private bool isOpeningOrder = false;

...


if (!isOpeningOrder ) 
{
    isOpeningOrder = true;
    ExecuteMarketOrderAsync( ... );
}


private void OnAsyncOpen(TradeResult result)
{
    if (!result.IsSuccessful)
        Stop();
    else 
        isOpeningOrder = false;
}

Now I've tested this in both Visual Mode and Non-Visual Mode with the backtester. The issue is, When I test the bot in Visual Mode at 500x or less speed, it works 100% as expected. It will place the trades at the right time, move the SL when I specify, etc... BUT, when I test it at 1000x speed or higher, and this includes disabling the Visual Mode entirely, this is where problems start coming in. Trades are executed, but there are some very specific situations where somehow the bot opens a second trade within possibly a minute or so of each other. 

Again, to reiterate, I only allow one trade to ever run at a time with this bot. I check to ensure that the active trades is 0, and I also check if an order is being opened at that time as shown above. Yet for some reason, the backtester ignores it in some very specific instances. It appears that there is a timing issue of some sort where a new bar is being painted almost at the same time that a SL is being hit so possibly two functions are being executed at the same time, and thus it ignores my boolean variable that tries to prevent a new trade from being opened at the same time. 

For the time being, I will attempt to introduce a manual timing delay to the execution of a trade to see if that makes a difference. I'm willing to share the entire source code with the official team so they could test for themselves. I've made some screenshots and have saved the parameters used so that it can be reproduced in the shortest amount of time.

I've used both ExecuteMarketOrder and ExecuteMarketOrderAsync to see if there would be a difference, but there was none.


@keno.clayton15
Replies

xabbu
04 Oct 2020, 10:00

Dear Keno,

did you try "Positions.Count " instead? For my cBot this works great under all mentioned conditions (high speed, non visual mode) to ensure, that I can`t open more trades then I want to.

Regards,

xabbu


@xabbu

keno.clayton15
04 Oct 2020, 10:12

RE:

xabbu said:

Dear Keno,

did you try "Positions.Count " instead? For my cBot this works great under all mentioned conditions (high speed, non visual mode) to ensure, that I can`t open more trades then I want to.

Regards,

xabbu

I've tried that before, but in this case I had to use Positions.FindAll because I wanted the bot to check for only the trades that it opened. Unfortunately, it didn't work. However, I did manage to come up with a reasonable workaround to this issue.

So what I've done is to move the logic from OnBar to my Positions.Closed event function. In other words, a new position can only be opened when a trade is closed, either by SL or TP closing. Doing this has prevented extra orders from being created within a few seconds of each other. The bug still exists, but at least there's a bit of a workaround possible.


@keno.clayton15

PanagiotisCharalampous
05 Oct 2020, 08:21

Hi keno.clayton15,

Please provide the complete cBot code and steps to reproduce the problem.

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

keno.clayton15
05 Oct 2020, 08:25

RE:

PanagiotisCharalampous said:

Hi keno.clayton15,

Please provide the complete cBot code and steps to reproduce the problem.

Best Regards,

Panagiotis 

Join us on Telegram

Is there an email address I can send the code to instead of posting it here? I'd prefer sharing it only with the devs for troubleshooting. Also, I've already come up with a workaround to the issue, but I'll disable the workaround so that you can reproduce the error.


@keno.clayton15

PanagiotisCharalampous
05 Oct 2020, 08:39

Hi keno.clayton15,

From what I read is probably not an error but a normal and expected behavior in a live trading environment. Your workaround is probably not just a workaround but the correct way to implement the functionality. I will not bother the devs if I don't confirm it is a bug. If you still want me to have a look, send the code and steps to reproduce the behavior at community@spotware.com.

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous