public void OrderFilledUnlockSequenceSubmitOpening(Order order) {
			List<List<Order>> ordersCloseFoundInKeys = new List<List<Order>>();
			lock (this.ordersCloseOpen) {
				foreach (List<Order> ordersClose in this.ordersCloseOpen.Keys) {
					if (ordersClose.Contains(order) == false) continue;
					ordersCloseFoundInKeys.Add(ordersClose);
				}
				foreach (List<Order> ordersCloseFound in ordersCloseFoundInKeys) {
					ordersCloseFound.Remove(order);
					if (ordersCloseFound.Count == 0) {
						List<Order> ordersOpen = this.ordersCloseOpen[ordersCloseFound];
						this.ordersCloseOpen.Remove(ordersCloseFound);
						if (ordersOpen.Count == 0) continue;
						this.orderProcessor.AppendOrderMessageAndPropagateCheckThrowOrderNull(order,
							"last CloseOpenSequence order filled, unlocking submission of [" + ordersOpen.Count + "]ordersOpen");
						foreach (Order submitting in ordersOpen) {
							OrderStateMessage omsg = new OrderStateMessage(submitting, OrderState.Submitting,
								"sequence cleared: [" + submitting.State + "]=>[" + OrderState.Submitting + "]"
								+ " for [" + ordersOpen.Count + "] fellow ordersOpen"
								+ " by orderClose=[" + order + "]");
							this.orderProcessor.UpdateOrderStateAndPostProcess(submitting, omsg);
						}
						BrokerProvider broker = ordersOpen[0].Alert.DataSource.BrokerProvider;
						ThreadPool.QueueUserWorkItem(new WaitCallback(broker.SubmitOrdersThreadEntry), new object[] { ordersOpen });
					}
				}
			}
		}
		public void InitializeSequence(List<Order> ordersClose, List<Order> ordersOpen) {
			lock (this.ordersCloseOpen) {
				this.ordersCloseOpen.Add(ordersClose, ordersOpen);
			}
			foreach (Order sequenced in ordersOpen) {
				OrderStateMessage omsg = new OrderStateMessage(sequenced, OrderState.SubmittingSequenced,
					"sequence initialized: [" + sequenced.State + "]=>[" + OrderState.SubmittingSequenced + "]"
					+ " for [" + ordersOpen.Count + "] fellow ordersOpen"
					+ " by [" + ordersClose.Count + "]ordersClose");
				this.orderProcessor.UpdateOrderStateAndPostProcess(sequenced, omsg);
			}
		}
		private void removeEmergencyLock(Order filledEmergencyOrder, OrderState stateCompletedOrInterrupted) {
			OrderPostProcessorEmergencyLock emergencyLock = new OrderPostProcessorEmergencyLock(filledEmergencyOrder);
			string msgPost = "EmergencyLock Removed [" + emergencyLock + "]";
			if (this.emergencyLocks.Contains(emergencyLock) == false) {
				string msg = "no EmergencyLock to remove: multiple QUIK callbacks? if u can find [" + msgPost
					+ "] earlier in thisOrder.Messages then it's ok";
				this.orderProcessor.AppendOrderMessageAndPropagateCheckThrowOrderNull(filledEmergencyOrder, msg);
				Assembler.PopupException(msg);
				//throw new Exception(msg);
				return;
			}

			lock (this.emergencyLocks) {
				this.emergencyLocks.Remove(emergencyLock);
			}
			OrderStateMessage omsgPost = new OrderStateMessage(filledEmergencyOrder, stateCompletedOrInterrupted, msgPost);
			this.orderProcessor.UpdateOrderStateAndPostProcess(filledEmergencyOrder, omsgPost);
		}
		public void OrderFilledUnlockSequenceSubmitOpening(Order orderClosed) {
			List<List<Order>> lockingClosesFound = new List<List<Order>>();
			lock (this.dictionaryLock) {
				// if among all the keys we have an order, then we should have Open orders sequenced
				foreach (List<Order> lockingCloseOrders in this.sequencerLockCloseOpen.Keys) {
					if (lockingCloseOrders.Contains(orderClosed) == false) continue;
					lockingClosesFound.Add(lockingCloseOrders);
				}
				// analyzing all locks for all symbols to find out whether this closed order released the lock
				foreach (List<Order> lockingCloseFound in lockingClosesFound) {
					// delete the locking order from the list (most likely containing 1 order)
					lockingCloseFound.Remove(orderClosed);
					if (lockingCloseFound.Count > 0) continue;

					// delete the list of locks from global dictionary
					List<Order> ordersOpen = this.sequencerLockCloseOpen[lockingCloseFound];
					this.sequencerLockCloseOpen.Remove(lockingCloseFound);
					this.orderProcessor.AppendOrderMessageAndPropagateCheckThrowOrderNull(orderClosed,
						"last CloseOpenSequence order filled, unlocking submission of [" 
						+ ordersOpen.Count + "]ordersOpen");
					if (ordersOpen.Count == 0) continue;

					// submitting all released opening orders
					foreach (Order submitting in ordersOpen) {
						OrderStateMessage omsg = new OrderStateMessage(submitting, OrderState.Submitting,
							"sequence cleared: [" + submitting.State + "]=>[" + OrderState.Submitting + "]"
							+ " for [" + ordersOpen.Count + "] fellow ordersOpen"
							+ " by orderClose=[" + orderClosed + "]");
						this.orderProcessor.UpdateOrderStateAndPostProcess(submitting, omsg);
					}
					BrokerProvider broker = ordersOpen[0].Alert.DataSource.BrokerProvider;
					ThreadPool.QueueUserWorkItem(new WaitCallback(broker.SubmitOrdersThreadEntryDelayed),
						new object[] { ordersOpen, ordersOpen[0].Alert.Bars.SymbolInfo.SequencedOpeningAfterClosedDelayMillis });
				}
			}
		}
		public virtual void ModifyOrderTypeAccordingToMarketOrderAs(Order order) {
			string msg = Name + "::ModifyOrderTypeAccordingToMarketOrderAs():"
				+ " Guid[" + order.GUID + "]" + " SernoExchange[" + order.SernoExchange + "]"
				+ " SernoSession[" + order.SernoSession + "]";

			order.CurrentBid = this.StreamingProvider.StreamingDataSnapshot.BestBidGetForMarketOrder(order.Alert.Symbol);
			order.CurrentAsk = this.StreamingProvider.StreamingDataSnapshot.BestAskGetForMarketOrder(order.Alert.Symbol);

			double priceBestBidAsk = this.StreamingProvider.StreamingDataSnapshot.BidOrAskFor(
				order.Alert.Symbol, order.Alert.PositionLongShortFromDirection);
				
			switch (order.Alert.MarketLimitStop) {
				case MarketLimitStop.Market:
					//if (order.PriceRequested != 0) {
					//	string msg1 = Name + "::OrderSubmit(): order[" + order + "] is MARKET, dropping Price[" + order.PriceRequested + "] replacing with current Bid/Ask ";
					//	order.addMessage(new OrderStateMessage(order, order.State, msg1));
					//	Assembler.PopupException(msg1);
					//	order.PriceRequested = 0;
					//}
					if (order.Alert.Bars == null) {
						msg = "order.Bars=null; can't align order and get Slippage; returning with error // " + msg;
						Assembler.PopupException(msg);
						//order.AppendMessageAndChangeState(new OrderStateMessage(order, OrderState.ErrorOrderInconsistent, msg));
						this.OrderProcessor.UpdateOrderStateAndPostProcess(order, new OrderStateMessage(order, OrderState.ErrorOrderInconsistent, msg));
						throw new Exception(msg);
					}

					switch (order.Alert.MarketOrderAs) {
						case MarketOrderAs.MarketZeroSentToBroker:
							order.PriceRequested = 0;
							msg = "SymbolInfo[" + order.Alert.Symbol + "/" + order.Alert.SymbolClass + "].OverrideMarketPriceToZero==true"
								+ "; setting Price=0 (Slippage=" + order.SlippageFill + ") //" + msg;
							break;
						case MarketOrderAs.MarketMinMaxSentToBroker:
							order.Alert.MarketLimitStop = MarketLimitStop.Limit;
							msg = this.ModifyOrderTypeAccordingToMarketOrderAsBrokerSpecificInjection(order);
							msg = "[" + order.Alert.MarketLimitStop + "]=>[" + MarketLimitStop.Limit + "](" + order.Alert.MarketOrderAs + ") // " + msg;
							break;
						case MarketOrderAs.LimitCrossMarket:
							order.Alert.MarketLimitStop = MarketLimitStop.Limit;
							msg = "PreSubmit: doing nothing for Alert.MarketOrderAs=[" + order.Alert.MarketOrderAs + "]"
								+ " //" + msg;
							break;
						case MarketOrderAs.LimitTidal:
							order.Alert.MarketLimitStop = MarketLimitStop.Limit;
							msg = "PreSubmit: doing nothing for Alert.MarketOrderAs=[" + order.Alert.MarketOrderAs + "]"
								+ " //" + msg;
							break;
						default:
							msg = "no handler for Market Order with Alert.MarketOrderAs[" + order.Alert.MarketOrderAs + "] // " + msg;
							OrderStateMessage newOrderState2 = new OrderStateMessage(order, OrderState.ErrorOrderInconsistent, msg);
							this.OrderProcessor.UpdateOrderStateAndPostProcess(order, newOrderState2);
							throw new Exception(msg);
					}
					//if (order.Alert.Bars.SymbolInfo.OverrideMarketPriceToZero == true) {
					//} else {
					//	if (order.PriceRequested == 0) {
					//		base.StreamingProvider.StreamingDataSnapshot.getAlignedBidOrAskTidalOrCrossMarketFromStreaming(
					//			order.Alert.Symbol, order.Alert.Direction, out order.PriceRequested, out order.SpreadSide, ???);
					//		order.PriceRequested += order.Slippage;
					//		order.PriceRequested = order.Alert.Bars.alignOrderPriceToPriceLevel(order.PriceRequested, order.Alert.Direction, order.Alert.MarketLimitStop);
					//	}
					//}
					//order.addMessage(new OrderStateMessage(order, order.State, msg));
					//Assembler.PopupException(msg);
					break;

				case MarketLimitStop.Limit:
					order.SpreadSide = OrderSpreadSide.ERROR;
					switch (order.Alert.Direction) {
						case Direction.Buy:
						case Direction.Cover:
							if (priceBestBidAsk <= order.PriceRequested) order.SpreadSide = OrderSpreadSide.BidTidal;
							break;
						case Direction.Sell:
						case Direction.Short:
							if (priceBestBidAsk >= order.PriceRequested) order.SpreadSide = OrderSpreadSide.AskTidal;
							break;
						default:
							msg += " No Direction[" + order.Alert.Direction + "] handler for order[" + order.ToString() + "]"
								+ "; must be one of those: Buy/Cover/Sell/Short";
							//orderProcessor.updateOrderStatusError(order, OrderState.Error, msg);
							OrderStateMessage newOrderState = new OrderStateMessage(order, OrderState.Error, msg);
							this.OrderProcessor.UpdateOrderStateAndPostProcess(order, newOrderState);
							throw new Exception(msg);
					}
					break;

				case MarketLimitStop.Stop:
				case MarketLimitStop.StopLimit:
					order.SpreadSide = OrderSpreadSide.ERROR;
					switch (order.Alert.Direction) {
						case Direction.Buy:
						case Direction.Cover:
							if (priceBestBidAsk >= order.PriceRequested) order.SpreadSide = OrderSpreadSide.AskTidal;
							break;
						case Direction.Sell:
						case Direction.Short:
							if (priceBestBidAsk <= order.PriceRequested) order.SpreadSide = OrderSpreadSide.BidTidal;
							break;
						default:
							msg += " No Direction[" + order.Alert.Direction + "] handler for order[" + order.ToString() + "]"
								+ "; must be one of those: Buy/Cover/Sell/Short";
							//orderProcessor.updateOrderStatusError(order, OrderState.Error, msg);
							OrderStateMessage newOrderState = new OrderStateMessage(order, OrderState.Error, msg);
							this.OrderProcessor.UpdateOrderStateAndPostProcess(order, newOrderState);
							throw new Exception(msg);
					}
					break;

				default:
					msg += " No MarketLimitStop[" + order.Alert.MarketLimitStop + "] handler for order[" + order.ToString() + "]"
						+ "; must be one of those: Market/Limit/Stop";
					//orderProcessor.updateOrderStatusError(order, OrderState.Error, msg);
					OrderStateMessage omsg = new OrderStateMessage(order, OrderState.Error, msg);
					this.OrderProcessor.UpdateOrderStateAndPostProcess(order, omsg);
					throw new Exception(msg);
			}
			order.AppendMessage(msg);
		}
		public virtual void OrderKillSubmitUsingKillerOrder(Order killerOrder) {
			if (string.IsNullOrEmpty(killerOrder.VictimGUID)) {
				throw new Exception("killerOrder.KillerForGUID=EMPTY");
			}
			if (killerOrder.VictimToBeKilled == null) {
				throw new Exception("killerOrder.VictimToBeKilled=null");
			}

			string msg = "State[" + killerOrder.State + "]"
				+ " [" + killerOrder.Alert.Symbol + "/" + killerOrder.Alert.SymbolClass + "]"
				+ " VictimToBeKilled.SernoExchange[" + killerOrder.VictimToBeKilled.SernoExchange + "]";
			msg = Name + "::UsingKillerOrder(): " + msg;
			Assembler.PopupException(msg);
			OrderStateMessage omsgKiller = new OrderStateMessage(killerOrder, OrderState.KillerPreSubmit, msg);
			this.OrderProcessor.UpdateOrderStateAndPostProcess(killerOrder, omsgKiller);

			this.OrderKillSubmit(killerOrder.VictimToBeKilled);
		}
		public void UpdateOrderStateNoPostProcess(Order order, OrderStateMessage newStateOmsg) {
			if (newStateOmsg.Order != order) {
				string msg = "sorry for athavism, but OrderStateMessage.Order should be equal to order here";
				throw new Exception(msg);
			}
			if (order == null) {
				string msg = "how come ORDER=NULL?";
			}
			if (order.Alert == null) {
				string msg = "how come ORDER.AlertNULL?";
			}
			if (order.Alert.OrderFollowed != order) {
				string msg = "order.Alert.OrderFollowed[" + order.Alert.OrderFollowed + "] != order[" + order + "]";
				//throw new Exception(msg);
			}
			if (order.State == newStateOmsg.State) {
				string msg = "Replace with AppendOrderMessage()! UpdateOrderStateNoPostProcess(): got the same OrderState[" + order.State + "]?";
				throw new Exception(msg);
			}

			if (newStateOmsg.State == OrderState.Active) {
				bool signalled = order.MreActiveCanCome.WaitOne(-1);
			}

			OrderState orderStatePriorToUpdate = order.State;
			order.State = newStateOmsg.State;
			order.StateUpdateLastTimeLocal = newStateOmsg.DateTime;
			this.DataSnapshot.SwitchLanesForOrderPostStatusUpdate(order, orderStatePriorToUpdate);

			this.EventDistributor.RaiseOrderStateChanged(this, order);
			this.appendOrderMessageAndPropagate(order, newStateOmsg);

			if (order.State == OrderState.Submitted) {
				order.MreActiveCanCome.Set();
			}
		}
		void PostProcessVictimOrder(Order victimOrder, OrderStateMessage newStateOmsg) {
			this.UpdateOrderStateNoPostProcess(victimOrder, newStateOmsg);
			switch (victimOrder.State) {
				case OrderState.KillPending:
				case OrderState.SLAnnihilated:
				case OrderState.TPAnnihilated:
					break;
				case OrderState.Submitting:
				case OrderState.Active:
				case OrderState.Filled:
					break;
				case OrderState.Killed:
					if (victimOrder.FindStateInOrderMessages(OrderState.SLAnnihilated)) {
						this.UpdateOrderStateNoPostProcess(victimOrder,
							new OrderStateMessage(victimOrder, OrderState.SLAnnihilated,
								"Setting State to the reason why it was killed"));
					}
					if (victimOrder.FindStateInOrderMessages(OrderState.TPAnnihilated)) {
						this.UpdateOrderStateNoPostProcess(victimOrder,
							new OrderStateMessage(victimOrder, OrderState.TPAnnihilated,
								"Setting State to the reason why it was killed"));
					}

					Order killerOrder = victimOrder.KillerOrder;
					this.UpdateOrderStateNoPostProcess(killerOrder,
						new OrderStateMessage(killerOrder, OrderState.KillerDone,
							"Victim.Killed => Killer.KillerDone"));
					break;
				default:
					string msg = "no handler for victimOrder[" + victimOrder + "]'s state[" + victimOrder.State + "]"
						+ "your BrokerProvider should call for Victim.States:{"
						//+ OrderState.KillSubmitting + ","
						+ OrderState.KillPending + ","
						//+ OrderState.Killed + ","
						//+ OrderState.SLAnnihilated + ","
						//+ OrderState.TPAnnihilated + "}";
						;
					throw new Exception(msg);
					break;
			}
		}
		void appendOrderMessageAndPropagate(Order order, OrderStateMessage omsg) {
			//log.Debug(omsg.Message);
			if (string.IsNullOrEmpty(omsg.Message)) {
				int a = 1;
			}
			omsg.Order.AppendMessageSynchronized(omsg);
			this.EventDistributor.RaiseOrderMessageAddedExecutionFormNotification(this, omsg);
		}
		public void CancelReplaceOrder(Order orderToReplace, Order orderReplacement) {
			string msgVictim = "expecting callback on successful REPLACEMENT completion [" + orderReplacement + "]";
			OrderStateMessage newOrderStateVictim = new OrderStateMessage(orderToReplace, OrderState.KillPending, msgVictim);
			this.UpdateOrderStateAndPostProcess(orderToReplace, newOrderStateVictim);

			orderReplacement.State = OrderState.Submitted;
			orderReplacement.IsReplacement = true;
			this.DataSnapshot.OrderAddSynchronizedAndPropagate(orderReplacement);

			if (orderToReplace.hasBrokerProvider("CancelReplaceOrder(): ") == false) {
				string msg = "CRAZY #65";
				Assembler.PopupException(msg);
				return;
			}
			orderToReplace.Alert.DataSource.BrokerProvider.CancelReplace(orderToReplace, orderReplacement);

			this.DataSnapshot.SerializerLogrotateOrders.HasChangesToSave = true;
			this.DataSnapshot.UpdateActiveOrdersCountEvent();
		}
		bool IsOrderEatable(Order order) {
			if (order.Alert.Strategy == null) return true;
			if (order.IsKiller) return true;
			if (order.Alert.Direction == Direction.Sell || order.Alert.Direction == Direction.Cover) {
				return true;
			}
			Account account = null;
			if (account == null) return true;
			if (account.CashAvailable <= 0) {
				string msg = "ACCOUNT_CASH_ZERO";
				OrderStateMessage newOrderState = new OrderStateMessage(order, OrderState.ErrorOrderInconsistent, msg);
				this.UpdateOrderStateAndPostProcess(order, newOrderState);
				return false;
			}
			return true;
		}
		private void submitReplacementOrderFor(Order rejectedOrderToReplace) {
			Order replacement = this.createEmergencyCloseOrderInsteadOfRejected(rejectedOrderToReplace);
			if (replacement == null) {
				string msgNoReplacement = "got NULL from CreateEmergencyCloseOrderInsteadOfRejected() for (" + rejectedOrderToReplace + "); ";
				Assembler.PopupException(msgNoReplacement);
				this.orderProcessor.AppendOrderMessageAndPropagateCheckThrowOrderNull(rejectedOrderToReplace, msgNoReplacement);
				return;
			}

			try {
				this.OPPsequencer.ReplaceLockingCloseOrder(rejectedOrderToReplace, replacement);

				double priceScript = replacement.Alert.DataSource.StreamingProvider.StreamingDataSnapshot
					.GetAlignedBidOrAskForTidalOrCrossMarketFromStreaming(
					replacement.Alert.Bars.Symbol, replacement.Alert.Direction, out replacement.SpreadSide, true);
				replacement.Alert.PositionAffected.ExitPriceScript = priceScript;

				if (replacement.Alert.Bars.SymbolInfo.ReSubmittedUsesNextSlippage == true) {
					replacement.SlippageIndex++;
				}

				int emergencyCloseAttemptsMax = replacement.Alert.Bars.SymbolInfo.EmergencyCloseAttemptsMax;
				string serno = "#[" + replacement.EmergencyCloseAttemptSerno + "]/[" + emergencyCloseAttemptsMax + "]";
				string msg_replacement = "This is an EMERGENCY replacement " + serno + " for order["
					+ replacement.EmergencyReplacementForGUID + "]; SlippageIndex[" + replacement.SlippageIndex + "]";
				this.orderProcessor.AppendOrderMessageAndPropagateCheckThrowOrderNull(replacement, msg_replacement);

				if (replacement.hasSlippagesDefined && replacement.noMoreSlippagesAvailable) {
					addMessageNoMoreSlippagesAvailable(replacement);
					replacement.SlippageIndex = replacement.Alert.Bars.SymbolInfo.getSlippageIndexMax(replacement.Alert.Direction);
				}
				double slippage = replacement.Alert.Bars.SymbolInfo.getSlippage(
					priceScript, replacement.Alert.Direction, replacement.SlippageIndex, false, false);
				replacement.SlippageFill = slippage;
				replacement.PriceRequested = priceScript + slippage;

				string msg = "Scheduling SubmitOrdersThreadEntry [" + replacement.ToString() + "] slippageIndex["
					+ replacement.SlippageIndex + "] through [" + replacement.Alert.DataSource.BrokerProvider + "]";
				OrderStateMessage omsg = new OrderStateMessage(replacement, OrderState.PreSubmit, msg);
				this.orderProcessor.UpdateOrderStateAndPostProcess(replacement, omsg);

				ThreadPool.QueueUserWorkItem(new WaitCallback(replacement.Alert.DataSource.BrokerProvider.SubmitOrdersThreadEntry),
					new object[] { new List<Order>() { replacement } });
			} catch (Exception e) {
				Assembler.PopupException("Replacement wasn't submitted [" + replacement + "]", e);
				OrderStateMessage omsg2 = new OrderStateMessage(replacement, OrderState.Error, e.Message);
				this.orderProcessor.UpdateOrderStateAndPostProcess(replacement, omsg2);
			}
		}
		private void closeEmergencyThreadEntry(Order rejectedExitOrder) {
			try {
				throwLogIfNotRejectedClosingOrder(rejectedExitOrder);
				throwLogAndAppendMessageIfNoEmergencyLockFor(rejectedExitOrder);
				throwLogAndAppendMessageIfNextAttemptReachesLimit(rejectedExitOrder);
			} catch (Exception) {
				return;
			}

			OrderState newState = rejectedExitOrder.ComplementaryEmergencyStateForError;
			string changeState = "ExitOrderCriticalState[" + rejectedExitOrder.State + "]=>[" + newState + "]";

			int millis = rejectedExitOrder.Alert.Bars.SymbolInfo.EmergencyCloseDelayMillis;
			if (millis > 0) {
				string msg = "Emergency sleeping millis[" + millis + "] before " + changeState;
				OrderStateMessage omsg = new OrderStateMessage(rejectedExitOrder, newState, msg);
				this.orderProcessor.UpdateOrderStateAndPostProcess(rejectedExitOrder, omsg);
				Thread.Sleep(millis);
			}

			string msg2 = changeState + " after having slept millis[" + millis + "]";
			if (rejectedExitOrder.State == newState) {
				// announced "sleeping xxx before"
				this.orderProcessor.AppendOrderMessageAndPropagateCheckThrowOrderNull(rejectedExitOrder, msg2);
			} else {
				// didnt announce "sleeping xxx before"
				OrderStateMessage omsg2 = new OrderStateMessage(rejectedExitOrder, newState, msg2);
				this.orderProcessor.UpdateOrderStateAndPostProcess(rejectedExitOrder, omsg2);
			}
			this.submitReplacementOrderFor(rejectedExitOrder);
		}
		public void AppendMessageSynchronized(OrderStateMessage omsg) {
			//this.messages.Push(omsg);
			this.messages.Enqueue(omsg);
		}
		public void RaiseOrderMessageAddedExecutionFormNotification(object sender, OrderStateMessage orderStateMessage) {
			if (this.OnOrderMessageAddedExecutionFormNotification == null) return;
			this.OnOrderMessageAddedExecutionFormNotification(sender, new OrderStateMessageEventArgs(orderStateMessage));
		}
		public void AppendOrderMessageAndRaiseOrderMessageAddedExecutionFormNotification(object sender, OrderStateMessage orderStateMessage) {
			orderStateMessage.Order.AppendMessageSynchronized(orderStateMessage);
			this.OrderEventDistributor.RaiseOrderMessageAddedExecutionFormNotification(sender, orderStateMessage);
		}
		public void SubmitEatableOrdersFromGui(List<Order> orders) {
			List<Order> ordersEatable = new List<Order>();
			foreach (Order order in orders) {
				if (this.IsOrderEatable(order) == false) continue;
				ordersEatable.Add(order);
				string msg = "Submitting Eatable Order From Gui";
				OrderStateMessage newOrderState = new OrderStateMessage(order, OrderState.Submitting, msg);
				this.UpdateOrderStateAndPostProcess(order, newOrderState);
			}
			if (ordersEatable.Count > 0) {
				BrokerProvider broker = extractSameBrokerProviderThrowIfDifferent(ordersEatable, "SubmitEatableOrders(): ");
				broker.SubmitOrders(ordersEatable);
			}
			this.DataSnapshot.SerializerLogrotateOrders.HasChangesToSave = true;
			this.DataSnapshot.UpdateActiveOrdersCountEvent();
		}
		private void throwLogAndAppendMessageIfNextAttemptReachesLimit(Order rejectedExitOrder) {
			if (rejectedExitOrder.IsEmergencyClose == false) return;
			int emergencyCloseAttemptsMax = rejectedExitOrder.Alert.Bars.SymbolInfo.EmergencyCloseAttemptsMax;
			if (rejectedExitOrder.EmergencyCloseAttemptSerno + 1 < emergencyCloseAttemptsMax) return;
			string msg = "no more EmergencyCloseAttempts:"
				+ " EmergencyCloseAttemptSerno[" + rejectedExitOrder.EmergencyCloseAttemptSerno
				+ "]>= EmergencyCloseAttemptsMax[" + emergencyCloseAttemptsMax + "]"
				+ " emergencyReplacement[" + rejectedExitOrder + "]";
			OrderStateMessage omsg = new OrderStateMessage(rejectedExitOrder, OrderState.EmergencyCloseLimitReached, msg);
			this.orderProcessor.UpdateOrderStateAndPostProcess(rejectedExitOrder, omsg);
			throw new Exception(msg);
		}
		public void KillOrderUsingKillerOrder(Order victimOrder) {
			Order killerOrder = this.CreateKillerOrder(victimOrder);
			//killerOrder.FromAutoTrading = false;
			if (killerOrder.hasBrokerProvider("KillOrder():") == false) {
				string msg = "CRAZY #63";
				Assembler.PopupException(msg);
				return;
			};
			string msgVictim = "expecting callback on successful KILLER completion [" + killerOrder + "]";
			OrderStateMessage newOrderStateVictim = new OrderStateMessage(victimOrder, OrderState.KillPending, msgVictim);
			this.UpdateOrderStateAndPostProcess(victimOrder, newOrderStateVictim);

			killerOrder.Alert.DataSource.BrokerProvider.OrderKillSubmitUsingKillerOrder(killerOrder);
		}
		private void throwLogIfEmergencyCloseInterrupted(Order replacementOrder) {
			Order reason4lock = this.GetReasonForLock(replacementOrder);
			lock (this.interruptedEmergencyLockReasons) {
				if (this.interruptedEmergencyLockReasons.Contains(reason4lock) == false) return;
			}
			string msg = "InterruptedEmergencyLockReasons.Contains reason4lock[" + reason4lock + "] for replacementOrder[" + replacementOrder + "]";
			Assembler.PopupException(msg);
			OrderStateMessage newOrderStateRejected = new OrderStateMessage(replacementOrder, OrderState.EmergencyCloseUserInterrupted, msg);
			this.orderProcessor.UpdateOrderStateAndPostProcess(replacementOrder, newOrderStateRejected);
			throw new Exception(msg);
		}
		public Order UpdateOrderStateByGuidNoPostProcess(string orderGUID, OrderState orderState, string message) {
			Order orderFound = this.DataSnapshot.OrdersSubmitting.FindByGUID(orderGUID);
			if (orderFound == null) {
				 orderFound = this.DataSnapshot.OrdersAll.FindByGUID(orderGUID);
			}
			if (orderFound == null) {
				string msg = "order[" + orderGUID + "] wasn't found; OrderProcessorDataSnapshot.OrderCount=[" + this.DataSnapshot.OrderCountThreadSafe + "]";
				throw new Exception(msg);
				//log.Fatal(msg, new Exception(msg));
				//return;
			}
			OrderState orderStateAbsorbed = (orderState == OrderState.LeaveTheSame) ? orderFound.State : orderState;
			if (orderStateAbsorbed != orderFound.State) {
				OrderStateMessage osm = new OrderStateMessage(orderFound, orderStateAbsorbed, message);
				UpdateOrderStateNoPostProcess(orderFound, osm);
			} else {
				this.AppendOrderMessageAndPropagateCheckThrowOrderNull(orderFound, message);
			}
			return orderFound;
		}
		public void SubmitReplacementOrderInsteadOfRejected(Order replacementOrder) {
			if (replacementOrder == null) {
				Assembler.PopupException("replacementOrder == null why did you call me?");
				return;
			}
			if (replacementOrder.hasBrokerProvider("PlaceReplacementOrderInsteadOfRejected(): ") == false) {
				return;
			}

			string msg = "Scheduling SubmitOrdersThreadEntry [" + replacementOrder.ToString() + "] slippageIndex["
				+ replacementOrder.SlippageIndex + "] through [" + replacementOrder.Alert.DataSource.BrokerProvider + "]";
			OrderStateMessage newOrderState = new OrderStateMessage(replacementOrder, OrderState.PreSubmit, msg);
			this.OrderProcessor.UpdateOrderStateAndPostProcess(replacementOrder, newOrderState);

			//this.BrokerProvider.SubmitOrdersThreadEntry(ordersFromAlerts);
			ThreadPool.QueueUserWorkItem(new WaitCallback(replacementOrder.Alert.DataSource.BrokerProvider.SubmitOrdersThreadEntry),
				new object[] { new List<Order>() { replacementOrder } });

			//this.orderProcessor.UpdateActiveOrdersCountEvent();
		}
		public void AppendOrderMessageAndPropagateCheckThrowOrderNull(Order order, string msg) {
			if (order == null) {
				throw new Exception("order=NULL! you don't want to get NullPointerException and debug it");
			}
			OrderStateMessage omsg = new OrderStateMessage(order, order.State, msg);
			this.appendOrderMessageAndPropagate(order, omsg);
		}
		public void AddMessageNoMoreSlippagesAvailable(Order order) {
			int slippageIndexMax = order.Alert.Bars.SymbolInfo.getSlippageIndexMax(order.Alert.Direction);
			string msg2 = "Reached max slippages available for [" + order.Alert.Bars.Symbol + "]"
				+ " order.SlippageIndex[" + order.SlippageIndex + "] > slippageIndexMax[" + slippageIndexMax + "]"
				+ "; Order will have slippageIndexMax[" + slippageIndexMax + "]"; 
			Assembler.PopupException(msg2);
			//orderProcessor.updateOrderStatusError(orderExecuted, OrderState.RejectedLimitReached, msg2);
			OrderStateMessage newOrderStateRejected = new OrderStateMessage(order, OrderState.RejectedLimitReached, msg2);
			this.OrderProcessor.UpdateOrderStateAndPostProcess(order, newOrderStateRejected);
		}
		void PostProcessKillerOrder(Order killerOrder, OrderStateMessage newStateOmsg) {
			switch (killerOrder.State) {
				case OrderState.JustCreated:
				case OrderState.KillerPreSubmit:
				case OrderState.KillerSubmitting:
				case OrderState.KillerBulletFlying:
				case OrderState.KillerDone:
					this.UpdateOrderStateNoPostProcess(killerOrder, newStateOmsg);
					break;
				default:
					string msg = "no handler for killerOrder[" + killerOrder + "]'s state[" + killerOrder.State + "]"
						+ "your BrokerProvider should call for Killer.States:{"
						+ OrderState.KillerBulletFlying + ","
						+ OrderState.KillerDone + "}";
					break;
					//throw new Exception(msg);
			}
		}
 public OrderStateMessageEventArgs(OrderStateMessage orderStateMessage)
 {
     this.OrderStateMessage = orderStateMessage;
 }
		public void UpdateOrderStateAndPostProcess(Order order, OrderStateMessage newStateOmsg, double priceFill = 0, double qtyFill = 0) {
			string msig = "UpdateOrderStateAndPostProcess(): ";

			try {
				if (order.State == OrderState.Killed) {
					int a = 1;
					// crawl in debugger if I can find VictimOrder.Alert.Executor.Script.OnAlertKilledCallback
					//this.RemovePendingAlertsForVictimOrderMustBePostKill(order, msig);
				}

				if (order.VictimToBeKilled != null) {
					this.PostProcessKillerOrder(order, newStateOmsg);
					return;
				}
				if (order.KillerOrder != null) {
					this.PostProcessVictimOrder(order, newStateOmsg);
					return;
				}

				if (order.hasBrokerProvider("handleOrderStatusUpdate():") == false) {
					string msg = "most likely QuikTerminal.CallbackOrderStatus got something wrong...";
					Assembler.PopupException(msg);
					return;
				}


				if (newStateOmsg.State == OrderState.Rejected && order.State == OrderState.EmergencyCloseLimitReached) {
					string prePostErrorMsg = "BrokerProvider CALLBACK DUPE: Status[" + newStateOmsg.State + "] delivered for EmergencyCloseLimitReached "
						//+ "; skipping PostProcess for [" + order + "]"
						;
					this.AppendOrderMessageAndPropagateCheckThrowOrderNull(order, prePostErrorMsg);
					return;
				}
				if (newStateOmsg.State == OrderState.Rejected && order.InEmergencyState) {
					string prePostErrorMsg = "BrokerProvider CALLBACK DUPE: Status[" + newStateOmsg.State + "] delivered for"
						+ " order.inEmergencyState[" + order.State + "] "
						//+ "; skipping PostProcess for [" + order + "]"
						;
					this.AppendOrderMessageAndPropagateCheckThrowOrderNull(order, prePostErrorMsg);
					return;
				}

				OrderCallbackDupesChecker dupesChecker = order.Alert.DataSource.BrokerProvider.OrderCallbackDupesChecker;
				if (dupesChecker != null) {
					string why = dupesChecker.OrderCallbackDupeResonWhy(order, newStateOmsg, priceFill, qtyFill);
					if (string.IsNullOrEmpty(why) == false) {
						string msgChecker = "OrderCallbackDupeResonWhy[" + why + "]; skipping PostProcess for [" + order + "]";
						this.AppendOrderMessageAndPropagateCheckThrowOrderNull(order, msgChecker);
						return;
					}
				}

				if (newStateOmsg.State == OrderState.Filled) {
					int a = 1;
				}

				/*if (qtyFill != 0) {
					if (order.QtyFill == 0 || order.QtyFill == -999) {
						order.QtyFill = qtyFill;
					} else {
						if (order.QtyFill != qtyFill && order.QtyFill != -qtyFill) {
							string msg = "got qtyFill[" + qtyFill + "] while order.QtyFill=[" + order.QtyFill
								+ "]; skipping update; trying to figure out why Filled orders get ZERO price from QUIK";
							order.AppendMessage(msg);
						}
					}
				}*/
				if (priceFill != 0) {
					if (order.PriceFill == 0 || order.PriceFill == -999.99) {
						order.PriceFill = priceFill;
						order.QtyFill = qtyFill;
					} else {
						bool marketWasSubstituted = order.Alert.MarketLimitStop == MarketLimitStop.Limit
								&& order.Alert.Bars.SymbolInfo.MarketOrderAs == MarketOrderAs.MarketMinMaxSentToBroker;
						if (order.PriceFill != priceFill && marketWasSubstituted == false) {
							string msg = "got priceFill[" + priceFill + "] while order.PriceFill=[" + order.PriceFill + "]"
								+ "; weird for Order.Alert.MarketLimitStop=[" + order.Alert.MarketLimitStop + "]";
							order.AppendMessage(msg);
						}
					}
				}
				this.UpdateOrderStateNoPostProcess(order, newStateOmsg);
				this.PostProcessOrderState(order, priceFill, qtyFill);
			} catch (Exception e) {
				string msg = "trying to figure out why SL is not getting placed - we didn't reach PostProcess??";
				this.PopupException(new Exception(msg, e));
			}
		}
		public override string OrderCallbackDupeResonWhy(
				Order order, OrderStateMessage newStateOmsg, double priceFill, double qtyFill) {
			return null;
		}
		public virtual void OrderPreSubmitEnrichCheckThrow(Order order) {
			string msg = Name + "::OrderPreSubmitChecker():"
				+ " Guid[" + order.GUID + "]" + " SernoExchange[" + order.SernoExchange + "]"
				+ " SernoSession[" + order.SernoSession + "]";
			if (this.StreamingProvider == null) {
				msg = " StreamingProvider=null, can't get last/fellow/crossMarket price // " + msg;
				OrderStateMessage newOrderState = new OrderStateMessage(order, OrderState.ErrorOrderInconsistent, msg);
				this.OrderProcessor.UpdateOrderStateAndPostProcess(order, newOrderState);
				throw new Exception(msg);
			}
			try {
				this.checkOrderThrowInvalid(order);
			} catch (Exception ex) {
				msg = ex.Message + " //" + msg;
				//orderProcessor.updateOrderStatusError(order, OrderState.ErrorOrderInconsistent, msg);
				OrderStateMessage newOrderState = new OrderStateMessage(order, OrderState.ErrorOrderInconsistent, msg);
				this.OrderProcessor.UpdateOrderStateAndPostProcess(order, newOrderState);
				throw new Exception(msg, ex);
			}

			order.CurrentBid = this.StreamingProvider.StreamingDataSnapshot.BestBidGetForMarketOrder(order.Alert.Symbol);
			order.CurrentAsk = this.StreamingProvider.StreamingDataSnapshot.BestAskGetForMarketOrder(order.Alert.Symbol);

			this.OrderPreSubmitEnrichBrokerSpecificInjection(order);

			// moved to orderProcessor::CreatePropagateOrderFromAlert()
			// this.ModifyOrderTypeAccordingToMarketOrderAs(order);

			if (order.Alert.Strategy.Script != null) {
				Order reason4lock = this.OrderProcessor.OPPemergency.GetReasonForLock(order);
				bool isEmergencyClosingNow = (reason4lock != null);
				//bool positionWasFilled = this.orderProcessor.positionWasFilled(order);
				if (order.Alert.IsEntryAlert && isEmergencyClosingNow) {	// && positionWasFilled
					//OrderState IRefuseUntilemrgComplete = this.orderProcessor.OPPemergency.getRefusalForEmergencyState(reason4lock);
					OrderState IRefuseUntilemrgComplete = OrderState.IRefuseOpenTillEmergencyCloses;
					msg = "Reason4lock: " + reason4lock.ToString();
					OrderStateMessage omsg = new OrderStateMessage(order, IRefuseUntilemrgComplete, msg);
					this.OrderProcessor.UpdateOrderStateAndPostProcess(order, omsg);
					throw new Exception(msg);
				}
			}
		}
		public abstract string OrderCallbackDupeResonWhy(
			Order order, OrderStateMessage newStateOmsg, double priceFill, double qtyFill);
		internal bool AnnihilateCounterpartyAlert(Alert alert) {
			if (alert.OrderFollowed == null) {
				string msg = "can't AnnihilateCounterparty: OrderFollowed=null for alert=[" + alert + "]";
				throw new Exception(msg);
				//this.executor.ThrowPopup(new Exception(msg));
			}
			if (alert.PositionAffected == null) {
				string msg = "can't AnnihilateCounterparty: PositionAffected=null for alert=[" + alert + "]";
				throw new Exception(msg);
				//this.executor.ThrowPopup(new Exception(msg));
			}
			if (alert.IsEntryAlert) {
				string msg = "can't AnnihilateCounterparty: alert.isEntryAlert for alert=[" + alert + "]";
				throw new Exception(msg);
				//this.executor.ThrowPopup(new Exception(msg));
			}

			OrderStateMessage newOrderState = null;
			if (alert.PositionAffected.ClosedByTakeProfitLogically) {	//copy from dispatcher (caller of a caller)
				string msg = "position ClosedByTakeProfit@" + alert.PriceScript + ", annihilating StopLoss";
				newOrderState = new OrderStateMessage(alert.OrderFollowed, OrderState.SLAnnihilated, msg);
			} else {
				string msg = "position ClosedByStopLoss@" + alert.PriceScript + ", annihilating TakeProfit";
				newOrderState = new OrderStateMessage(alert.OrderFollowed, OrderState.TPAnnihilated, msg);
			}
			executor.OrderProcessor.UpdateOrderStateNoPostProcess(alert.OrderFollowed, newOrderState);
			executor.OrderProcessor.KillOrderUsingKillerOrder(alert.OrderFollowed);

			//this.executor.RemovePendingExitAlert(alert, "MarketRealtime:AnnihilateCounterparty(): ");
			bool removed = this.executor.ExecutionDataSnapshot.AlertsPendingRemove(alert);
			return true;
		}
Beispiel #32
0
 public void AppendMessageSynchronized(OrderStateMessage omsg)
 {
     //this.messages.Push(omsg);
     this.messages.Enqueue(omsg);
 }