Why is ExitLong / ExitShort not closing position?

I have this code but it won’t close positions. What could be wrong?

Thanks!

if (Position.MarketPosition == MarketPosition.Long)
{
if (Limit_1_Market_2 == 1)
{
PrintLog( 1, " ClosePosition: Long Limit");
ExitLong();
}
else if (Limit_1_Market_2 == 2)
{
PrintLog( 1, " ClosePosition: Long Market");
ExitLong();
}
}
else if (Position.MarketPosition == MarketPosition.Short)
{
if (Limit_1_Market_2 == 1)
{
PrintLog( 1, " ClosePosition: Short Limit");
ExitShort();
}
else if (Limit_1_Market_2 == 2)
{
PrintLog( 1, " ClosePosition: Short Market");
ExitShort();
}
}

Many things could be wrong, it’s hard to say without more context. How are you entering your orders? Are you using stops or targets? Are you seeing your print statements in your logs?
This is from the Managed order docs section about “Internal Order Handling Rules that Reduce Unwanted Positions”

ManagedExitIgnored

I found the problem in Position.MarketPosition. It always returns “Flat”. No matter if there is an active position or not.
The SetStop loss is set at the beginning of the strategy. Cancelling stop loss order while having a position is risky if the price goes against the strategy. I’m not sure why ninjascript would do that.

Indeed, it is risky. But in a fast market there’s risk the other way too. If you exit the position and leave your stops/targets, they could get filled and put you back in a position. I suspect the intent is to err on the side of caution. Since you are exiting anyway, if the stops/targets are cancelled first then the exit order is filled you are guaranteed flat (possibly with some slippage). The other way around risks getting you unknowingly into a position that could totally wreck your account.

Thank you for the insight. I’ve simplified the strategy logic here. with no setstoploss, it still isn’t closing the position.

namespace NinjaTrader.NinjaScript.Strategies
{
public class MyCustomStrategy : Strategy
{
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @“Enter the description for your new custom Strategy here.”;
Name = “MyCustomStrategy”;
Calculate = Calculate.OnBarClose;
EntriesPerDirection = 1;
EntryHandling = EntryHandling.AllEntries;
IsExitOnSessionCloseStrategy = true;
ExitOnSessionCloseSeconds = 30;
IsFillLimitOnTouch = false;
MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
OrderFillResolution = OrderFillResolution.Standard;
Slippage = 0;
StartBehavior = StartBehavior.WaitUntilFlat;
TimeInForce = TimeInForce.Gtc;
TraceOrders = false;
RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
StopTargetHandling = StopTargetHandling.PerEntryExecution;
BarsRequiredToTrade = 20;
// Disable this property for performance gains in Strategy Analyzer optimizations
// See the Help Guide for additional information
IsInstantiatedOnEachOptimizationIteration = true;
}
else if (State == State.Configure)
{
}
}

	protected override void OnBarUpdate()
	{
		Print( PositionAccount.MarketPosition );

		ExitLong();
		ExitShort();
	}

}

}

I’m a little confused by your simplified strategy. There is no entry, therefore nothing to exit. Strategy order functions can only affect orders created by the strategy. If you want to cancel orders and exit positions created elsewhere you need to use Account.Flatten(Instrument) which affects all orders and the position for the specified instrument on the account.

The ExitLong() documentation has this example. Does this work for you?

protected override void OnBarUpdate()
{
    if (CurrentBar < 20)
        return;
 
    // Only enter if at least 10 bars has passed since our last entry
    if ((BarsSinceEntryExecution() > 10 || BarsSinceEntryExecution() == -1) && CrossAbove(SMA(10), SMA(20), 1))
        EnterLong("SMA Cross Entry");
 
    // Exits position
    if (CrossBelow(SMA(10), SMA(20), 1))
        ExitLong();
}

Found the problem. I called CancelAllOrders right after the Exit statement. That cancelled the exit order, which never got executed and the position never got closed.

2 Likes