Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Order stacking, Atm stacking or propper Quantity calculations

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

    Order stacking, Atm stacking or propper Quantity calculations

    Hello!

    I have one interesting task that I'm trying to solve here (Indicator, that will show user what will be the result of a target and stop (if it will be hit)): I have modified ATM identifier to count the possible result of a target or stop for particular order.
    But there is one problem, when you are stacking orders on top of each other it recognizes them as separate orders (same with ATM) as a result you are getting wrong calculations.

    For few days I was looking through the forum and NT8 guide, but I couldn't find a workable solution that would merge orders, or somehow defines that orders sitting at the same price, so they should be added in calculations.

    I will add the part of the code and .cs file itself, hope someone will help me figure out how these calculations can be achieved.
    + I've added screenshots showing the behavior of the indicator at this stage.

    Code:
    private void CheckActiveAtmStrategyOrders()
    {
    if (account == null)
    return;
    
    lock (account.Orders)
    {
    lock (atmDictionary)
    {
    atmDictionary.Clear();
    
    foreach (Order order in account.Orders)
    {
    if (order.GetOwnerStrategy() != null && order.Instrument == Instrument && Instrument.FullName == instrument && !Order.IsTerminalState(order.OrderState))
    {
    AtmStrategy atm = order.GetOwnerStrategy() as AtmStrategy;
    
    if (!atmDictionary.ContainsKey(atm.Id))
    {
    AtmOrders atmOrders = new AtmOrders();
    atmOrders.Id = atm.Id;
    atmOrders.Name = atm.DisplayName;
    atmDictionary.Add(atm.Id, atmOrders);
    }
    
    foreach (KeyValuePair<long, AtmOrders> atmDict in atmDictionary)
    {
    if (atmDict.Key == atm.Id)
    {
    if (order.Name.Contains("Stop") && !atmDict.Value.stops.Contains(order))
    atmDict.Value.stops.Add(order);
    
    if (order.Name.Contains("Target") && !atmDict.Value.targets.Contains(order))
    atmDict.Value.targets.Add(order);
    }
    }
    }
    }
    }
    }
    }

    Code:
    protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
    {
    if (dxBrushList.IsNullOrEmpty() || ChartControl.Properties.ChartTraderVisibility == ChartTraderVisibility.Collapsed)
    return;
    
    
    if (!IsInHitTest)
    {
    double offset = ChartControl.OwnerChart.ChartTrader.Properties.Ord erDisplayBarLength * ChartPanel.W / 87 + 150;
    
    lock (atmDictionary)
    {
    if (atmDictionary.Count == 0)
    return;
    
    int j = 0;
    for (int i = 0; i < atmDictionary.Count; i++)
    {
    if (j >= dxBrushList.Count) j = 0;
    
    SharpDX.Direct2D1.Brush textBrushDx = dxBrushList[j];
    
    foreach (Order order in atmDictionary.ElementAt(i).Value.stops)
    {
    SharpDX.DirectWrite.TextLayout textLayout = new SharpDX.DirectWrite.TextLayout(NinjaTrader.Core.Gl obals.DirectWriteFactory,
    "- $"+ Convert.ToInt32(Math.Abs(((order.StopPrice - entryprice)/TickSize)*TickSize * Instrument.MasterInstrument.PointValue * order.Quantity)), textFormat, ChartPanel.X + ChartPanel.W,
    textFormat.FontSize);
    float x = (float)(ChartPanel.X + ChartPanel.W - offset);
    float y = chartScale.GetYByValue(order.StopPrice) - textLayout.Metrics.Height/2;
    SharpDX.Vector2 textPoint = new SharpDX.Vector2(x, y);
    
    RenderTarget.DrawTextLayout(textPoint, textLayout, textBrushDx, SharpDX.Direct2D1.DrawTextOptions.NoSnap);
    textLayout.Dispose();
    
    
    }
    
    foreach (Order order in atmDictionary.ElementAt(i).Value.targets)
    {
    SharpDX.DirectWrite.TextLayout textLayout = new SharpDX.DirectWrite.TextLayout(NinjaTrader.Core.Gl obals.DirectWriteFactory,
    "+ $"+ Convert.ToInt32(Math.Abs(((entryprice - order.LimitPrice)/TickSize)*TickSize * Instrument.MasterInstrument.PointValue * order.Quantity)), textFormat, ChartPanel.X + ChartPanel.W,
    textFormat.FontSize);
    float x = (float)(ChartPanel.X + ChartPanel.W - offset);
    float y = chartScale.GetYByValue(order.LimitPrice) - textLayout.Metrics.Height/2;
    SharpDX.Vector2 textPoint = new SharpDX.Vector2(x, y);
    
    RenderTarget.DrawTextLayout(textPoint, textLayout, textBrushDx, SharpDX.Direct2D1.DrawTextOptions.NoSnap);
    textLayout.Dispose();
    }
    j++;
    }
    }
    }
    }
    Click image for larger version

Name:	AnyDesk_mW6q5Ke0vQ.png
Views:	327
Size:	34.4 KB
ID:	1187817Click image for larger version

Name:	AnyDesk_OyQMGURxpr.png
Views:	190
Size:	38.0 KB
ID:	1187818Click image for larger version

Name:	AnyDesk_sWzwrJNsyH.png
Views:	185
Size:	58.1 KB
ID:	1187819Click image for larger version

Name:	AnyDesk_Ki73Jmd5MU.png
Views:	192
Size:	72.2 KB
ID:	1187820

    #2
    Hello Againmain1,

    Thanks for your post.

    I am glad your are using the AtmStrategyIdentifier script I made. As mentioned in the description on User App Share, the script does not have functionality to handle orders at the same price level.

    You would have to loop through the stops and targets orders that are collected and stored AtmOrders.Stops List and AtmOrders.Targets Lists to see if any lie on the same price level. If there are orders on the same price level that have the same entry, you would have to modify the PnL calculation to account for the total quantity of all of the orders at that price level. You could then draw this aggregated PnL calculation, and ignore drawing for the other orders at the same price level.

    The quantity of an order object can be read with Order.Quantity. The Stop Price can be read with Order.StopPrice, and the Limit Price can be read with Order.LimitPrice.

    Order object reference - https://ninjatrader.com/support/help...html?order.htm

    I do not have any exact modifications to share as I would have included this functionality when I originally made this script.

    I hope this helps, and feel free to share any modifications you make back on User App Share!.

    Last edited by NinjaTrader_Jim; 02-01-2022, 07:56 AM.

    Comment


      #3
      Jim, thanks for the great script!
      As a kick-start for new ideas, it's just perfect.
      I've wanted to make an indication of each order result for a long time, but I couldn't figure out how to do it before. Your script helped me.
      But so far I could not make it calculate correctly with multiple orders to share it to everybody, because I'm not an expert in programming. At the moment, I just stopped at indicating the number of ticks and their distance from the entry price.
      I would be glad to share the script in User App Share if it is ever going to be finished :/

      Comment

      Latest Posts

      Collapse

      Topics Statistics Last Post
      Started by Geovanny Suaza, 02-11-2026, 06:32 PM
      0 responses
      647 views
      0 likes
      Last Post Geovanny Suaza  
      Started by Geovanny Suaza, 02-11-2026, 05:51 PM
      0 responses
      368 views
      1 like
      Last Post Geovanny Suaza  
      Started by Mindset, 02-09-2026, 11:44 AM
      0 responses
      108 views
      0 likes
      Last Post Mindset
      by Mindset
       
      Started by Geovanny Suaza, 02-02-2026, 12:30 PM
      0 responses
      571 views
      1 like
      Last Post Geovanny Suaza  
      Started by RFrosty, 01-28-2026, 06:49 PM
      0 responses
      573 views
      1 like
      Last Post RFrosty
      by RFrosty
       
      Working...
      X