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.
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);
}
}
}
}
}
}
}
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++;
}
}
}
}

Comment