Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Issues with the StopLoss for Long entry with Unmanged Order entry

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Issues with the StopLoss for Long entry with Unmanged Order entry

    Hi
    I need some help. I am using unmanaged order entry, and everything seems to work as expected besides the stop loss order for the long entry.
    I cannot see why this fails but it does not work. Proditarhet is 2 points = 8 ticks stoploss is 1 point = 4 ticks.
    As can b e seen from the screenshot there are some massive losers here all with Exit on session close, but these should have been exited long before with a loss of 1 point.
    The issue seems to be only for the long stop loss order.

    Code:
    namespace NinjaTrader.NinjaScript.Strategies
    {
    public class Strat : Strategy
    {
    private Order shortEntry = null;
    private Order longEntry = null;
    private Order targetLong = null;
    private Order targetShort = null;
    private Order stopLossShort = null;
    private Order stopLossLong = null;
    private string oco;
    
    private int ProfitDistance = 8;
    private int StopDistance = 4;
    
    private int sumFilledLong = 0; 
    private int sumFilledShort = 0; 
    
    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    Description = @"Enter the description for your new custom Strategy here.";
    Name = "Strat";
    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 = 2;
    IsUnmanaged = true;
    
    IsInstantiatedOnEachOptimizationIteration = true;
    }
    else if (State == State.Configure)
    {
    }
    else if (State == State.Realtime)
    {
    var aStrategyPosition = this.Position;
    var aRealAccount = PositionAccount;
    // convert any old historical order object references
    // to the new live order submitted to the real-time account
    if (shortEntry != null)
    shortEntry = GetRealtimeOrder(shortEntry);
    if (longEntry != null)
    longEntry = GetRealtimeOrder(longEntry);
    if (targetLong != null)
    targetLong = GetRealtimeOrder(targetLong);
    if (targetShort != null)
    targetShort = GetRealtimeOrder(targetShort);
    if (stopLossShort != null)
    stopLossShort = GetRealtimeOrder(stopLossShort);
    if (stopLossLong != null)
    stopLossLong = GetRealtimeOrder(stopLossLong);
    }
    }
    
    protected override void OnBarUpdate()
    {
    
    if (CurrentBar < 20)
    return;
    
    
    
    string scenario = GetScenario();
    
    if (longEntry == null && shortEntry == null && Position.MarketPosition == MarketPosition.Flat)
    {
    
    if (State == State.Historical)
    oco = DateTime.Now.ToString() + CurrentBar + "entry";
    else
    oco = GetAtmStrategyUniqueId() + "entry";
    
    if (scenario == "1")
    {
    
    longEntry = SubmitOrderUnmanaged(0, OrderAction.Buy, OrderType.StopMarket, 1, 0, High[0] + 1 * TickSize, oco, "Long_IB");
    shortEntry = SubmitOrderUnmanaged(0, OrderAction.SellShort, OrderType.StopMarket, 1, 0, Low[0] - 1 * TickSize, oco, "Short_IB");
    
    }
    }
    }
    
    private string GetScenario()
    {
    string scenario = "0";
    if (High[0] <= High[1] && Low[0] >= Low[1])
    {//Inside Bar
    scenario = "1";
    
    }
    else if (High[0] >= High[1] && Low[0] >= Low[1])
    {
    scenario = "2u";
    
    }
    else if (High[0] <= High[1] && Low[0] <= Low[1])
    {
    scenario = "2d";
    
    }
    else if (High[0] > High[1] && Low[0] < Low[1])
    {
    scenario = "3";
    
    }
    
    return scenario;
    }
    
    
    protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
    {
    
    
    if (longEntry != null && longEntry == execution.Order)
    {
    if (execution.Order.OrderState == OrderState.Filled
    || execution.Order.OrderState == OrderState.PartFilled
    || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
    {
    
    sumFilledLong += execution.Quantity;
    
    if (State == State.Historical)
    oco = DateTime.Now.ToString() + CurrentBar + "LongExits";
    else
    oco = GetAtmStrategyUniqueId() + "LongExits";
    
    if (stopLossLong == null && targetLong == null)
    {
    SubmitOrderUnmanaged(0, OrderAction.Sell, OrderType.StopMarket, execution.Order.Filled,0,execution.Order.AverageFi llPrice - StopDistance * TickSize, oco, "StopLossLong");
    SubmitOrderUnmanaged(0, OrderAction.Sell, OrderType.Limit, execution.Order.Filled, execution.Order.AverageFillPrice + ProfitDistance * TickSize, 0, oco, "TargetLong");
    }
    else
    {
    // Submit exit orders for partial fills
    if (execution.Order.OrderState == OrderState.PartFilled)
    {
    ChangeOrder(stopLossLong, execution.Order.Filled, 0, execution.Order.AverageFillPrice - StopDistance * TickSize);
    ChangeOrder(targetLong, execution.Order.Filled, execution.Order.AverageFillPrice + ProfitDistance * TickSize, 0);
    }
    // Update our exit order quantities once orderstate turns to filled and we have seen execution quantities match order quantities
    else if (execution.Order.OrderState == OrderState.Filled && sumFilledLong == execution.Order.Filled)
    {
    // Stop-Loss order for OrderState.Filled
    ChangeOrder(stopLossLong, execution.Order.Filled, 0, execution.Order.AverageFillPrice - StopDistance * TickSize);
    ChangeOrder(targetLong, execution.Order.Filled, execution.Order.AverageFillPrice + ProfitDistance * TickSize, 0);
    }
    
    }
    
    // Resets the entryOrder object and the sumFilled counter to null / 0 after the order has been filled
    if (execution.Order.OrderState != OrderState.PartFilled && sumFilledLong == execution.Order.Filled)
    {
    longEntry = null;
    sumFilledLong = 0;
    }
    }
    }
    if (shortEntry != null && shortEntry == execution.Order)
    {
    if (execution.Order.OrderState == OrderState.Filled
    || execution.Order.OrderState == OrderState.PartFilled
    || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
    {
    // We sum the quantities of each execution making up the entry order
    sumFilledShort += execution.Quantity;
    
    if (State == State.Historical)
    oco = DateTime.Now.ToString() + CurrentBar + "ShortExits";
    else
    oco = GetAtmStrategyUniqueId() + "ShortExits";
    
    if (stopLossShort == null && targetShort == null)
    {
    SubmitOrderUnmanaged(0, OrderAction.BuyToCover, OrderType.StopMarket, execution.Order.Filled, 0, execution.Order.AverageFillPrice + StopDistance * TickSize, oco, "StopLossShort");
    SubmitOrderUnmanaged(0, OrderAction.BuyToCover, OrderType.Limit, execution.Order.Filled, execution.Order.AverageFillPrice - ProfitDistance * TickSize, 0, oco, "TargetShort");
    }
    else
    {
    // Submit exit orders for partial fills
    if (execution.Order.OrderState == OrderState.PartFilled)
    {
    ChangeOrder(stopLossShort, execution.Order.Filled, 0, execution.Order.AverageFillPrice + StopDistance * TickSize);
    ChangeOrder(targetShort, execution.Order.Filled, execution.Order.AverageFillPrice - ProfitDistance * TickSize, 0);
    }
    // Update our exit order quantities once orderstate turns to filled and we have seen execution quantities match order quantities
    else if (execution.Order.OrderState == OrderState.Filled && sumFilledShort == execution.Order.Filled)
    {
    // Stop-Loss order for OrderState.Filled
    ChangeOrder(stopLossShort, execution.Order.Filled, 0, execution.Order.AverageFillPrice + StopDistance * TickSize);
    ChangeOrder(targetShort, execution.Order.Filled, execution.Order.AverageFillPrice - ProfitDistance * TickSize, 0);
    }
    }
    
    // Resets the entryOrder object and the sumFilled counter to null / 0 after the order has been filled
    if (execution.Order.OrderState != OrderState.PartFilled && sumFilledShort == execution.Order.Filled)
    {
    shortEntry = null;
    sumFilledShort = 0;
    }
    }
    }
    
    // Reset our stop order and target orders' Order objects after our position is closed.
    if ((stopLossLong != null && stopLossLong == execution.Order) || (targetLong != null && targetLong == execution.Order))
    {
    if (execution.Order.OrderState == OrderState.Filled
    || execution.Order.OrderState == OrderState.PartFilled)
    {
    stopLossLong = null;
    targetLong = null;
    }
    }
    if ((stopLossShort != null && stopLossShort == execution.Order) || (targetShort != null && targetShort == execution.Order))
    {
    if (execution.Order.OrderState == OrderState.Filled
    || execution.Order.OrderState == OrderState.PartFilled)
    {
    stopLossShort = null;
    targetShort = null;
    }
    }
    }
    
    
    protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string nativeError)
    {
    
    
    // Assign Order objects here
    // This is more reliable than assigning Order objects in OnBarUpdate, as the assignment is not guaranteed to be complete if it is referenced immediately after submitting
    if (order.Name == "Short_IB")
    shortEntry = order;
    else if (order.Name == "Long_IB")
    longEntry = order;
    else if (order.Name == "StopLossLong")
    stopLossLong = order;
    else if (order.Name == "TargetLong")
    targetLong = order;
    else if (order.Name == "StopLossShort")
    stopLossShort = order;
    else if (order.Name == "TargetShort")
    targetShort = order;
    
    if (longEntry != null && longEntry == order)
    {
    // Reset the longTop object to null if order was cancelled without any fill
    if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
    {
    longEntry = null;
    sumFilledLong = 0;
    }
    }
    
    if (shortEntry != null && shortEntry == order)
    {
    // Reset the shortTop object to null if order was cancelled without any fill
    if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
    {
    shortEntry = null;
    sumFilledShort = 0;
    }
    }
    //sets all targets and stops to null if one of them is canceled
    //PLEASE NOTE: setting IOrders to null ***DOES NOT*** cancel them
    if ((targetLong != null && targetLong == order)
    || (stopLossLong != null && stopLossLong == order)
    || (targetShort != null && targetShort == order)
    || (stopLossShort != null && stopLossShort == order)
    )
    {
    if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
    {
    targetLong = stopLossLong = targetShort = stopLossShort = null;
    }
    }
    }
    }
    }
    Attached Files

    #2
    Hello SuneSorgenfrei,

    I can provide a link to an unmanaged example of modifying a stop and limit for trailing and chase behavior.


    You will need to provide output from prints showing the issue.

    You said something is failing. What is failing?

    Is a condition not evaluating as true when you expect?

    Is an order not being submitted when you expect?

    Is an order being modified to a price you do not expect?

    Print the order information, if there is a condition print the time of the bar and all values in the condition. Enable TraceOrders. Provide the output saved to a text file.

    Below is a link to a forum post that demonstrates using Print() and TraceOrders to understand behavior.
    Chelsea B.NinjaTrader Customer Service

    Comment

    Latest Posts

    Collapse

    Topics Statistics Last Post
    Started by NullPointStrategies, Yesterday, 05:17 AM
    0 responses
    55 views
    0 likes
    Last Post NullPointStrategies  
    Started by argusthome, 03-08-2026, 10:06 AM
    0 responses
    132 views
    0 likes
    Last Post argusthome  
    Started by NabilKhattabi, 03-06-2026, 11:18 AM
    0 responses
    73 views
    0 likes
    Last Post NabilKhattabi  
    Started by Deep42, 03-06-2026, 12:28 AM
    0 responses
    45 views
    0 likes
    Last Post Deep42
    by Deep42
     
    Started by TheRealMorford, 03-05-2026, 06:15 PM
    0 responses
    49 views
    0 likes
    Last Post TheRealMorford  
    Working...
    X