Chart resize causes strategy to submit erroneous orders

Shtick Hustler

Well-known member
Joined
Oct 15, 2020
Posts
106
Likes
46
The current version of my strategy was re-written to submit orders directly rather than using the ctx.signal() method, and then call the orders from onSignal() (ala the example study SampleMACrossStrategy.java).

Did this because I was getting intermittent errors saying something like 'signal descriptor does not exist' which would prevent trades from occurring.

Everything is functional with the new Strat and I am able to:
- enter positions
- exit positions
- enter stops after orders fill
- cancel stops after position closes

But, if I resize my chart while Strat is running, it will sometimes start submitting orders...lots and lots of (live) orders (I've only run this in the SIM).
I assume what's happening is that historical trade order submissions are leaking through to realtime and causing order submissions--both stop orders and market entry orders.

Another chart operation that will cause these orders to appear is adding a study.

For example: here's the Strat in nonactive state.

761

Here it is, active:
762

Here it is after a resize:

763

In a matter of seconds it submitted 478 orders that were filled, with many more waiting for a fill.

It seems to me that there should be a firewall between historical trade data and realtime, and this should not happen (assuming it is historical trades that are triggering this).

Of course it's possible something is wrong in my code, but the SDK should have some protection built-in against situations like this, IMO.

Needless to say I can't run this live in its current state. I'd recommend anyone deciding to enable direct order submission in their Strats to test thoroughly before going live.

If anyone has experienced this issue, or has ideas on why this might be happening and how to fix it, I'd appreciate hearing from you.
 

Shtick Hustler

Well-known member
Joined
Oct 15, 2020
Posts
106
Likes
46
UPDATE

I've confirmed that reloading historical data is the cause of the order submissions, and I've found a workaround:

Create a flag in the study for initial bar date time setting

Java:
boolean latestBarDateTimeSet = false;


Within calculate, init the latest bar if strategy is active, and turn off flag so it's set only once.
If using the replayer, rewind to your desired date time before activating strategy.

Java:
var seriesEndTime = Instant.ofEpochMilli(series.getEndTime(index)).atZone(ZoneId.systemDefault()).toLocalDateTime();

if (!latestBarDateTimeSet && getState() == Enums.StrategyState.ACTIVE) {
  latestBarDateTime = seriesEndTime;
  latestBarDateTimeSet = true;
}

Update the current bar and latest bar

Java:
    if (getState() == Enums.StrategyState.ACTIVE) {
        currentBarDateTime = Instant.ofEpochMilli(series.getEndTime(index)).atZone(ZoneId.systemDefault()).toLocalDateTime();
       
        // only set latestBarDateTime to seriesEndTime if it's later than latestBarDateTime
        //
        latestBarDateTime = seriesEndTime.isAfter(latestBarDateTime) ? seriesEndTime : latestBarDateTime;

    }

Add this method to return true if we're in realtime:

Java:
    public static boolean inRealTime(LocalDateTime currentBarDateTime, LocalDateTime latestBarDateTime) {

        // if the current bar is not equal to or greater than the latest bar
        //      we're not in realtime anymore Toto
        //
        boolean res =  !currentBarDateTime.isBefore(latestBarDateTime);
        if (!res)
            System.out.println("\n\n!!!!!!!! currentBarDateTime: " + currentBarDateTime + " is in the past, before latestBarDateTime: " + latestBarDateTime);

        return res;

    }

Now, anytime you make a call to submit orders, run a check on inRealTime()

Java:
    if (inRealTime(currentBarDateTime, latestBarDateTime) {
      orderCtx.submitOrders(orders);
    }

After implementing this and repeating the resize I did above, I get hundreds to thousands of these println statements in the log:

Code:
!!!!!!!! currentBarDateTime: 2021-04-22T05:05:44.924 is in the past, before lastBarDateTime: 2021-04-23T09:15:14.140


!!!!!!!! currentBarDateTime: 2021-04-22T05:22:04.536 is in the past, before lastBarDateTime: 2021-04-23T09:15:14.140


!!!!!!!! currentBarDateTime: 2021-04-22T05:38:17.300 is in the past, before lastBarDateTime: 2021-04-23T09:15:14.140


!!!!!!!! currentBarDateTime: 2021-04-22T05:56:58.696 is in the past, before lastBarDateTime: 2021-04-23T09:15:14.140


!!!!!!!! currentBarDateTime: 2021-04-22T06:02:34.476 is in the past, before lastBarDateTime: 2021-04-23T09:15:14.140



Seems to me like this logic should be built-in to MW.

If any commercial developers are using submitOrders() in their code, please share how you've handled this issue.
 
Last edited:
Top