I have a strategy which is submitting unmanaged orders to multiple accounts simultaneously. Every now and then it fails to submit to my rithmic accounts but never fails to submit to my sim accounts, when it doesn't work there's no log or error generated, my print statement says it's submitting the order but there's nothing returned in order trace or in logs. The trace shows the other order submissions that did work, which always seem to be on my sim accounts, my rithmic account sometimes gets the order and sometimes doesn't. I'm using this code to add the account objects to an array which works every time:
foreach(Account acct in Account.All){
if(acct.Name.Contains(copy_trade_name) || acct.Name=="Sim101" || acct.Name=="Sim102"){
Print(copy_trade_name.ToString() + " ACCOUNT FOUND, ADDING TO LIST: " + acct.Name);
acct.ExecutionUpdate += OnExecutionUpdate;
copy_accounts[acct_num]=acct;
acct_num++;
}
}
Print("FOUND " + acct_num.ToString() + " " + copy_trade_name.ToString() + " ACCOUNTS");
And I have this code to submit the initial entry order which always prints the print() statements to the output window:
for(int a=0;a<acct_num;a++){
Print("Entering Long Order at " + Close[0].ToString() + " on " + copy_accounts[a].Name.ToString());
buy_orders[a]=copy_accounts[a].CreateOrder(Instrument, OrderAction.Buy, OrderType.Market, TimeInForce.Day, Convert.ToInt32(DefaultQuantity), 0, 0, "", "Long Order", null);
copy_accounts[0].Submit(new[] {buy_orders[a]});
}
I'm using OnExecutionUpdate to create the stop and limit orders, when the order submission fails for the rithmic account nothing in this is printed and no trace or log or error is created:
private void OnExecutionUpdate(object sender, ExecutionEventArgs e)
{
int a = Array.IndexOf(copy_accounts, e.Execution.Account);
if (buy_orders[a] != null && buy_orders[a] == e.Execution.Order){
if (e.Execution.Order.OrderState == OrderState.Filled || e.Execution.Order.OrderState == OrderState.PartFilled || (e.Execution.Order.OrderState == OrderState.Cancelled && e.Execution.Order.Filled > 0)){
sums_filled[a] += e.Execution.Quantity;
if (e.Execution.Order.OrderState == OrderState.Filled && sums_filled[a] == e.Execution.Order.Filled && e.Execution.Order.OrderAction==OrderAction.Buy && e.Execution.Order.OrderType==OrderType.Market){
String ocoString = string.Format("unmanageexitdoco{0}", DateTime.Now.ToString("hhmmssffff"));
Print("Submitting Long Stop Order on " + e.Execution.Account.Name.ToString() + " at " + (e.Execution.Order.AverageFillPrice - stop_loss).ToString());
stop_orders[a]=e.Execution.Account.CreateOrder(Instrument, OrderAction.Sell, OrderType.StopMarket, TimeInForce.Day, Convert.ToInt32(DefaultQuantity), 0, e.Execution.Order.AverageFillPrice - stop_loss, ocoString, "Long Stop Loss", null);
Print("Submitting Long Limit Order on " + e.Execution.Account.Name.ToString() + " at " + (e.Execution.Order.AverageFillPrice + profit_target).ToString());
limit_orders[a]=e.Execution.Account.CreateOrder(Instrument, OrderAction.Sell, OrderType.Limit, TimeInForce.Day, Convert.ToInt32(DefaultQuantity), e.Execution.Order.AverageFillPrice + profit_target, 0, ocoString, "Long Take Profit", null);
e.Execution.Account.Submit(new[] {stop_orders[a], limit_orders[a]});
Print("OCO String: " + ocoString);
}
if (e.Execution.Order.OrderState == OrderState.Filled && sums_filled[a] == e.Execution.Order.Filled && e.Execution.Order.OrderAction==OrderAction.Sell && e.Execution.Order.OrderType==OrderType.Market){
String ocoString = string.Format("unmanageexitdoco{0}", DateTime.Now.ToString("hhmmssffff"));
Print("Submitting Short Stop Order on " + e.Execution.Account.Name.ToString() + " at " + (e.Execution.Order.AverageFillPrice + stop_loss).ToString());
stop_orders[a]=e.Execution.Account.CreateOrder(Instrument, OrderAction.Buy, OrderType.StopMarket, TimeInForce.Day, Convert.ToInt32(DefaultQuantity), 0, e.Execution.Order.AverageFillPrice + stop_loss, ocoString, "Short Stop Loss", null);
Print("Submitting Short Limit Order on " + e.Execution.Account.Name.ToString() + " at " + (e.Execution.Order.AverageFillPrice - profit_target).ToString());
limit_orders[a]=e.Execution.Account.CreateOrder(Instrument, OrderAction.Buy, OrderType.Limit, TimeInForce.Day, Convert.ToInt32(DefaultQuantity), e.Execution.Order.AverageFillPrice - profit_target, 0, ocoString, "Short Take Profit", null);
e.Execution.Account.Submit(new[] {stop_orders[a], limit_orders[a]});
Print("OCO String: " + ocoString);
}
if (e.Execution.Order.OrderState != OrderState.PartFilled && sums_filled[a] == e.Execution.Order.Filled){
buy_orders[a] = null;
sums_filled[a] = 0;
open_orders[a] = true;
open_position_num++;
}
}
}
if ((stop_orders[a] != null && stop_orders[a] == e.Execution.Order) || (limit_orders[a] != null && limit_orders[a] == e.Execution.Order)){
if (e.Execution.Order.OrderState == OrderState.Filled || e.Execution.Order.OrderState == OrderState.PartFilled){
Print("FLAT on " + e.Execution.Account.Name.ToString());
stop_orders[a] = null;
limit_orders[a] = null;
open_orders[a] = false;
open_position_num--;
}
if (e.Execution.Order.OrderState == OrderState.Rejected){
// Stop loss order was rejected !!!!
Print("!!!!====---- Stop Loss or Limit Order Rejected, Flattening Account " + copy_accounts[a].Name.ToString() + " ----====!!!!");
copy_accounts[a].CancelAllOrders(Instrument);
}
}
}
When it does work I see the same prints for the rithmic accounts and the orders work the same way as they do on the sim accounts.
If it were failing all the time I would know it was definitely my code but since it's intermittent I'm looking for confirmation if there's anything obviously incorrect with my code or if this could be a rithmic/connection issue, or if there are any other known issues related to any of this. I'll also mention when I enable the strategy, I enable it on a Sim account and it finds the other rithmic accounts which I am connected through using the built-in RIthmic for NinjaTrader connection which connects succesfully and works fine to submit orders to when this strategy is only working with that account or with any other strategies that are not submitting orders to multiple accounts.
In the Orders tab the failed order still shows 'Initialized' with the ability to cancel it, the other orders all show Filled/Cancelled. In the executions tab I only see the orders which worked on the sim accounts in this case.
Orders:
Log/order trace:

Comment