Object error after exit

Hey, all. I need a little bit of help, here.

I have an Indicator that creates an order when certain conditions are met, then cancels it if it doesn’t trigger within a certain amount of time, and then immediately begins scanning for the next entry. That part works just fine.

It’s also supposed to return to looking for new entries after a previously entered order is triggered, and then that position is ultimately exited. That part does not work. It gives me the “Object reference not set to an instance of an object” error.

Here is the relevant code:

	private void OnPositionUpdate(object sender, PositionEventArgs e)
	{
		if (e.MarketPosition == MarketPosition.Flat)
		{ 
			Print("No open positions.");
			p = "Flat";
		}
		else if (p == null)
		{	p = e.Position.ToString(); }
	}

..........................
	[inside OnBarUpdate]

	if (o != null)
		{   
			if (myAccount != null && subbed == false)
			{
				myAccount.PositionUpdate += OnPositionUpdate;
				subbed	= true;
			}
			
			Print("Order " + o.Name.ToString() + " = " + o.OrderState.ToString());
			// Check if it was cancelled by the user, by your code, or rejected by the broker
			if (o.OrderState == OrderState.Cancelled || o.OrderState == OrderState.Rejected)
			{
				orderPlaced = false;
				// Clean up the reference
				o = null;
			}
			if (p != null)
			{
				Print("Position = " + p);
				if (o.OrderState == OrderState.Filled && p == "Flat")
				{
					orderPlaced = false;
					o = null;
					p = null;
				}
			}
		}

I can’t see anything in here that would cause the error. It has to be in these pieces of code, though, because nothing else in the Indicator is affected by the position state. Only o and p are changing.

The goal is to get the Indicator to return to basically State.Configure without having to F5 the whole chart, because NinjaTrader has a tendency to crash whenever I do that mid-session. Looking at my code, however, it seems to me that it should work.

When the position is updated, p, a string variable, is set to whatever the current position is. It starts out as null, and should stay that way until OnPositionUpdate triggers, at which point it is set to the current position, represented in string form.

When the position is ultimately exited, p is then set to “Flat.” When p is “Flat” and OrderState is Filled, p then gets set back to null, which is the default state. So, everything should work fine.

No references to p or o are made while they are null. At least, not that I can see.

One curiosity, which I still don’t see as being anything that would cause this error, is that the problem only seems to happen after the Indicator has caused an entered-and-exited position, and then has had to cancel an order due to a non-trigger situation.

At that point, OrderState is Cancelled, but that is still a non-null value, so it should not cause the “Object reference” error.

Any ideas?

Thanks in advance!

I would debug it and isolate which part is giving off the error. Are you able to consistently get that error? If you think it’s within that portion of code, try putting print statements before the “if (o != null)” portion and throughout the rest of that code. If there is any print statements that occur before the error occurs, then you know it’s between the last print statement and the one that didn’t print.

Also, I’m not sure what you mean by “The goal is to get the Indicator to return to basically State.Configure”. I don’t think there is a way to go back to that state, unless you mean a state that is identical to it, in which case, wouldn’t you just find a place to reset all the values as in a Flat Position?

Just with the prints that I already have, I see this in the Output screen:

Order Entry = Cancelled
Position = Flat
Indicator ‘PinBarsWithOrder’: Error on calling ‘OnBarUpdate’ method on bar 2447: Object reference not set to an instance of an object.

So, it’s somehow related to the most recent order having been cancelled. It only happens after a position has been entered and then exited. If it just places and cancels, places and cancels, places and cancels, etc. it works. But after an order triggers and then the position is later closed, the next cancelled order breaks everything.

And, yes, it is consistent. I have two indicators, essentially identical, each of which handles only the long or the short side of the potential entry. It doesn’t matter which indicator’s order gets triggered, after that position is exited, on the next cancelled order this error comes up.

Getting things back to the state of a Flat position, with the order variable being cleared, as though no order had ever been placed, is the goal. So, yes, that is exactly what I am trying to do - set everything back to flat, pre-order state.

  • You’re subbing to OPU in OBU

  • You’re checking for OrderState updates inside OBU (use OOU, OEU)

  • You’re using a nullable string to track positions, why not just use the Position object?

    There’s too many things going on and you cannot guarantee the order in which they run, OBU may run before OPU for example. But I think the last if block is causing the error.

    Look at the sequence, Order cancelled or Rejected > o is nulled

    Immediately after you do this check:

                if (p != null)
    
                {
    
    Print("Position = " + p);
    
    if (o.OrderState == OrderState.Filled && p == "Flat")
    
                    {
    
    ……
    
    p = null;
    
                    }
    

p can only be nulled here, so this check

if (o.OrderState == OrderState.Filled

when o is null, will give you the error you got.

2 Likes

Wait, what? A simple comparison can give you an Object reference error?

If o is null, than o.OrderState cannot possibly match the non-null condition that it’s being compared to, so it should just ignore that if.

I am using a string variable instead of Position values for some reason that I can’t entirely remember, but I know it had something to do with the fact that certain Position calls don’t work in Indicators. They only work in Strategies. I beat my head against that wall for quite a while before I discovered the workaround.

Also, the code that you referred to as being the section responsible for causing the error, is itself inside an if that is only true when o != null, so it can’t be null at that point.

Yes, a comparison can give an object reference error.

“If o is null, than o.OrderState cannot possibly match the non-null condition that it’s being compared to, so it should just ignore that if.”

No, that’s not how it works. You’re accessing o.OrderState to compare it to something, .o.OrderState doesn’t exist if it has been nulled.

“Also, the code that you referred to as being the section responsible for causing the error, is itself inside an if that is only true when o != null, so it can’t be null at that point.”

I know, but then you null it INSIDE this section and immediately afterwards do a comparison on the nulled object. You need a != null check on ‘o’ in this instance before trying to access o.OrderState

Also, check your Print, the error happens exactly here and literally tells you Position = “Flat” and the order was cancelled so o has been nulled as per your condition.

“I am using a string variable instead of Position values for some reason that I can’t entirely remember, but I know it had something to do with the fact that certain Position calls don’t work in Indicators. They only work in Strategies. I beat my head against that wall for quite a while before I discovered the workaround.”

I don’t know what you mean it doesn’t work in indicators, I believe all the same functions are available.

2 Likes

Okay, so what I ended up doing was change the order of evaluation. I also realized that I had left out some critical elses.

	if (o != null)
	{   
		Print("Order = " + o.OrderState.ToString() + ", Position = " + p);
		if (myAccount != null && subbed == false)
		{
			myAccount.PositionUpdate += OnPositionUpdate;
			subbed	= true;
		}
			
		if (p != null)
		{
			Print("Order = " + o.OrderState.ToString() + ", Position = " + p);
			if (o.OrderState == OrderState.Filled && p == "Flat")
			{
				orderPlaced = false;
				o = null;
				p = null;
			}
			else if (o.OrderState == OrderState.Cancelled && p == "Flat")
			{
				orderPlaced = false;
				o = null;
			}
		}
		else if (o.OrderState == OrderState.Cancelled || o.OrderState == OrderState.Rejected)
		{
			Print("Order = " + o.OrderState.ToString() + ", Position = " + p);
			orderPlaced = false;
			o = null;
		}
		else if (p == null && o.OrderState == OrderState.Filled)
		{
			Print("Order = " + o.OrderState.ToString() + ", Position = " + p);
			orderPlaced = false;
			o = null;
		}
	}

This version seems to work under all of the test conditions under which I was receiving the error. Now, only one comparison to o.Whatever gets executed on each entry into the loop. And, since all of those conditions result in the nulling of o, the loop is then ignored until the next order is generated.

Thank you for your help!