I have a decent order management algo here for my unmanaged system which takes fills and issues stops/targets. However, once in a blue moon I encounter an issue with my "unique lableling" methodology which results in having a position that doesn't get matched stops/targets.
To start, entry orders are issued a "unique identifier" based on the instrument and time entered. I believe the problem stems from near-simultaneous executions which receive identical entry names:
if (BarsInProgress == 0 && !noTrading)
{
// First, cancel any outstanding entry orders:
if (CurrentBar > barNumberOfOrder && entryOrder != null)
{
CancelOrder(entryOrder);
// Need to reset entryOrder to null in the order update:
entryOrder = null;
}
if (Signal == 1)
{
newPosition = Instrument.FullName + "_" + "Long_" + Time[0];
entryOrder = SubmitOrder(0, OrderAction.Buy, OrderType.Limit, positionSize, Instrument.MasterInstrument.Round2TickSize(CRG.LongLimitEntryPrice), 0, entryOrders.Count.ToString(), newPosition);
}
if (Signal == -1)
{
newPosition = Instrument.FullName + "_" + "Short_" + Time[0];
entryOrder = SubmitOrder(0, OrderAction.SellShort, OrderType.Limit, positionSize, Instrument.MasterInstrument.Round2TickSize(CRG.ShortLimitEntryPrice), 0, entryOrders.Count.ToString(), newPosition);
}
if (entryOrder != null)
{
// Add the entry order's token to the token array:
entryOrderTokens.Add(entryOrder.Token);
// Add the entry order to the entryOrder array:
entryOrders.Add(entryOrder);
entryOrder = null;
// Here, we assign barNumberOfOrder the CurrentBar, so we can check how many bars pass after our order is placed.
barNumberOfOrder = CurrentBar;
}
}
protected override void OnExecution(IExecution execution)
{
try
{
// First, loop through the entry orders to see if this execution is linked to an entry order:
if (entryOrders.Count !=0)
{
for (int i = entryOrders.Count - 1; i >= 0; i --)
{
// Create a temporary entry order container:
IOrder localEntryOrder = entryOrders[i];
// If the execution token matches the token to the entry order we were looking for:
if (localEntryOrder.Token == execution.Order.Token)
{
//Print(execution.ToString());
// Is the order filled/partially filled OR has the order been cancelled & filled?
//if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
if (execution.Order.OrderState == OrderState.Filled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
//if (execution.Order.OrderState == OrderState.Filled)
{
if (Position.MarketPosition == MarketPosition.Long)
{
targetExitPrice = Position.AvgPrice + CRG.TargetExit;
trailingStopPrice = Position.AvgPrice - CRG.StopExit;
stopOrder = SubmitOrder(0, OrderAction.Sell, OrderType.Stop, execution.Order.Quantity, 0, trailingStopPrice, execution.Order.Name, "Stop Order");
targetOrder = SubmitOrder(0, OrderAction.Sell, OrderType.Limit, execution.Order.Quantity, targetExitPrice, 0, execution.Order.Name, "Target Order");
}
if (Position.MarketPosition == MarketPosition.Short)
{
targetExitPrice = Position.AvgPrice - CRG.TargetExit;
trailingStopPrice = Position.AvgPrice + CRG.StopExit;
stopOrder = SubmitOrder(0, OrderAction.BuyToCover, OrderType.Stop, execution.Order.Quantity, 0, trailingStopPrice, execution.Order.Name, "Stop Order");
targetOrder = SubmitOrder(0, OrderAction.BuyToCover, OrderType.Limit, execution.Order.Quantity, targetExitPrice, 0, execution.Order.Name, "Target Order");
}
// Add stop order to the stop order list
if (stopOrder != null)
{
stopOrders.Add(stopOrder);
stopOrder = null;
}
// Add target order to the target order list.
if (targetOrder != null)
{
targetOrders.Add(targetOrder);
targetOrder = null;
}
// Resets the entryOrder object to null after the order has been filled or partially filled
//if (execution.Order.OrderState != OrderState.PartFilled)
if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.Cancelled)
{
entryOrders.RemoveAt(i);
entryOrder = null;
}
}
}
}
}
// Second, loop through the target orders to see if this execution is linked to a target order:
if (targetOrders.Count != 0)
{
for (int i = targetOrders.Count - 1; i >= 0; i --)
{
IOrder localTargetOrder = targetOrders[i];
// If the execution token matches the token to the entry order we were looking for:
if (localTargetOrder.Token == execution.Order.Token)
{
// Is the order filled/partially filled OR has the order been cancelled & filled?
//if (execution.Order.OrderState == OrderState.Filled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.Cancelled)
{
//CancelOrder(targetOrders[i]);
targetOrders.RemoveAt(i);
}
}
}
}
// Third, loop through the stop orders to see if this execution is linked to a stop order:
if (stopOrders.Count != 0)
{
for (int i = stopOrders.Count - 1; i >= 0; i --)
{
IOrder localStopOrder = stopOrders[i];
// If the execution token matches the token to the entry order we were looking for:
if (localStopOrder.Token == execution.Order.Token)
{
// Is the order filled/partially filled OR has the order been cancelled & filled?
//if (execution.Order.OrderState == OrderState.Filled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.Cancelled)
{
//CancelOrder(stopOrders[i]);
stopOrders.RemoveAt(i);
}
}
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
Thanks-
CG
PS I have left just a few details out in terms of the code but everything needed for the positioning algo is there -

Comment