Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

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 AaronKTradingForum, Today, 03:44 PM
    1 response
    2 views
    0 likes
    Last Post AaronKTradingForum  
    Started by Felix Reichert, 04-26-2024, 02:12 PM
    11 responses
    72 views
    0 likes
    Last Post Felix Reichert  
    Started by junkone, 04-28-2024, 02:19 PM
    7 responses
    82 views
    1 like
    Last Post junkone
    by junkone
     
    Started by pechtri, 06-22-2023, 02:31 AM
    11 responses
    136 views
    0 likes
    Last Post Nyman
    by Nyman
     
    Started by ageeholdings, 05-01-2024, 05:22 AM
    4 responses
    27 views
    0 likes
    Last Post ageeholdings  
    Working...
    X