public void RemovePendingExitAlertPastDueClosePosition(Alert alert) {
			string msig = "RemovePendingEntryCloneToExitAlertClosePosition(): ";
			this.RemovePendingExitAlert(alert, msig);
			//bool checkPositionOpenNow = true;
			//if (this.checkPositionCanBeClosed(alert, msig, checkPositionOpenNow) == false) return;

			//"Excuse me, what bar is it now?" I'm just guessing! does BrokerProvider knows to pass Bar here?...
			Bar barFill = (this.IsStreaming) ? alert.Bars.BarStreamingCloneReadonly : alert.Bars.BarStaticLast;
			alert.FillPositionAffectedEntryOrExitRespectively(barFill, barFill.ParentBarsIndex, barFill.Close, alert.Qty, 0, 0);
			alert.SignalName += " RemovePendingExitAlertClosePosition Forced";
			// REFACTORED_POSITION_HAS_AN_ALERT_AFTER_ALERTS_CONSTRUCTOR we can exit by TP or SL - position doesn't have an ExitAlert assigned until Position.EntryAlert was filled!!!
			//alert.PositionAffected.ExitAlertAttach(alert);

			bool absenseInPositionsOpenNowIsAnError = true;
			this.ExecutionDataSnapshot.MovePositionOpenToClosed(alert.PositionAffected, absenseInPositionsOpenNowIsAnError);
		}
		public void RemovePendingEntry(Alert alert) {
			string msig = "RemovePendingEntry(): ";

			//"Excuse me, what bar is it now?" I'm just guessing! does BrokerProvider knows to pass Bar here?...
			Bar barFill = (this.IsStreaming) ? alert.Bars.BarStreamingCloneReadonly : alert.Bars.BarStaticLast;
			alert.FillPositionAffectedEntryOrExitRespectively(barFill, barFill.ParentBarsIndex, barFill.Close, alert.Qty, 0, 0);
			alert.SignalName += " RemovePendingEntryAlertClosePosition Forced";
		}
		public void CallbackAlertFilledMoveAroundInvokeScript(Alert alertFilled, Quote quote,
					 int barFillRelno, double priceFill, double qtyFill, double slippageFill, double commissionFill) {
			string msig = " CallbackAlertFilledMoveAroundInvokeScript(" + alertFilled + ", " + quote + ")";
			List<Alert> alertsNewAfterAlertFilled = new List<Alert>();
			List<Position> positionsOpenedAfterAlertFilled = new List<Position>();
			List<Position> positionsClosedAfterAlertFilled = new List<Position>();

			//"Excuse me, what bar is it now?" I'm just guessing! does BrokerProvider knows to pass Bar here?...
			Bar barFill = (this.IsStreaming) ? alertFilled.Bars.BarStreamingCloneReadonly : alertFilled.Bars.BarStaticLast;
			if (barFillRelno != barFill.ParentBarsIndex) {
				string msg = "barFillRelno[" + barFillRelno + "] != barFill.ParentBarsIndex["
					+ barFill.ParentBarsIndex + "]; barFill=[" + barFill + "]";
				Assembler.PopupException(msg);
			}
			if (priceFill == -1) {
				string msg = "won't set priceFill=-1 for alert [" + alertFilled + "]";
				throw new Exception(msg);
			}
			if (alertFilled.PositionAffected == null) {
				string msg = "CallbackAlertFilled can't do its job: alert.PositionAffected=null for alert [" + alertFilled + "]";
				throw new Exception(msg);
			}
			if (alertFilled.IsEntryAlert) {
				if (alertFilled.PositionAffected.EntryFilledBarIndex != -1) {
					string msg = "DUPE: CallbackAlertFilled can't do its job: alert.PositionAffected.EntryBar!=-1 for alert [" + alertFilled + "]";
					throw new Exception(msg);
				} else {
					string msg = "initializing EntryBar=[" + barFill + "] on AlertFilled";
				}
			} else {
				if (alertFilled.PositionAffected.ExitFilledBarIndex != -1) {
					string msg = "DUPE: CallbackAlertFilled can't do its job: alert.PositionAffected.ExitBar!=-1 for alert [" + alertFilled + "]";
					throw new Exception(msg);
					return;
				} else {
					string msg = "initializing ExitBar=[" + barFill + "] on AlertFilled";
				}
			}

			if (quote == null) {
				quote = this.DataSource.StreamingProvider.StreamingDataSnapshot.LastQuoteGetForSymbol(alertFilled.Symbol);
				// TODO: here quote will have NO_PARENT_BARS, since StreamingDataSnapshot contains anonymous quote;
				// I should keep per-timeframe / per-distributionChannel LastQuote to have ParentBar= different StreamingBar 's
				// bindStreamingBarForQuoteAndPushQuoteToConsumers(quoteSernoEnrichedWithUnboundStreamingBar.Clone());
			}
			alertFilled.QuoteLastWhenThisAlertFilled = quote;
			try {
				alertFilled.FillPositionAffectedEntryOrExitRespectively(barFill, barFillRelno, priceFill, qtyFill, slippageFill, commissionFill);
			} catch (Exception ex) {
				string msg = "REMOVE_FILLED_FROM_PENDING? DONT_USE_Bar.ContainsPrice()?";
				Assembler.PopupException(msg + msig, ex);
				//Debugger.Break();
			}
			bool removed = this.ExecutionDataSnapshot.AlertsPendingRemove(alertFilled);
			if (removed == false) {
				Debugger.Break();
			}
			if (alertFilled.IsEntryAlert) {
				// position has its parent alert in Position.ctor()
				//// REFACTORED_POSITION_HAS_AN_ALERT_AFTER_ALERTS_CONSTRUCTOR
				//alert.PositionAffected.EntryCopyFromAlert(alert);
				this.ExecutionDataSnapshot.PositionsMasterOpenNewAdd(alertFilled.PositionAffected);
				positionsOpenedAfterAlertFilled.Add(alertFilled.PositionAffected);
			} else {
				//// REFACTORED_POSITION_HAS_AN_ALERT_AFTER_ALERTS_CONSTRUCTOR we can exit by TP or SL - position doesn't have an ExitAlert assigned until Alert was filled!!!
				//alertFilled.PositionAffected.ExitAlertAttach(alertFilled);
				this.ExecutionDataSnapshot.MovePositionOpenToClosed(alertFilled.PositionAffected);
				positionsClosedAfterAlertFilled.Add(alertFilled.PositionAffected);
			}

			bool willPlace = this.Backtester.IsBacktestingNow == false && this.OrderProcessor != null && this.IsAutoSubmitting;
			bool setStatusSubmitting = this.IsStreaming && this.IsAutoSubmitting;

			PositionPrototype proto = alertFilled.PositionAffected.Prototype;
			if (proto != null) {
				// 0. once again, set ExitAlert to What was actually filled, because prototypeEntry created SL & TP, which were both written into ExitAlert;
				// so if we caught the Loss and SL was executed, position.ExitAlert will still contain TP if we don't set it here
				bool exitIsDifferent = alertFilled.PositionAffected.ExitAlert != null && alertFilled.PositionAffected.ExitAlert != alertFilled;
				if (alertFilled.IsExitAlert && exitIsDifferent) {
					alertFilled.PositionAffected.ExitAlertAttach(alertFilled);
				}
				// 1. alert.PositionAffected.Prototype.StopLossAlertForAnnihilation and TP will get assigned
				alertsNewAfterAlertFilled = this.PositionPrototypeActivator.AlertFilledCreateSlTpOrAnnihilateCounterparty(alertFilled);
				// quick check: there must be {SL+TP} OR Annihilator
				//this.BacktesterFacade.IsBacktestingNow == false &&
				if (alertFilled.IsEntryAlert) {
					if (proto.StopLossAlertForAnnihilation == null) {
						string msg = "NONSENSE@Entry: proto.StopLossAlert is NULL???..";
						throw new Exception(msg);
					}
					if (proto.TakeProfitAlertForAnnihilation == null) {
						string msg = "NONSENSE@Entry: proto.TakeProfitAlert is NULL???..";
						throw new Exception(msg);
					}
					if (alertsNewAfterAlertFilled.Count == 0) {
						string msg = "NONSENSE@Entry: alertsNewSlAndTp.Count=0"
							+ "; this.PositionPrototypeActivator.AlertFilledCreateSlTpOrAnnihilateCounterparty(alertFilled)"
							+ " should return 2 alerts; I don't want to create new list from {proto.SL, proto.TP}";
						throw new Exception(msg);
					}
				}
				if (alertFilled.IsExitAlert) {
					if (alertsNewAfterAlertFilled.Count > 0) {
						string msg = "NONSENSE@Exit: there must be no alerts (got " + alertsNewAfterAlertFilled.Count + "): killer works silently";
						throw new Exception(msg);
					}
				}

				if (alertsNewAfterAlertFilled.Count > 0 && willPlace) {
					this.OrderProcessor.CreateOrdersSubmitToBrokerProviderInNewThreadGroups(alertsNewAfterAlertFilled, setStatusSubmitting, true);

					// 3. Script using proto might move SL and TP which require ORDERS to be moved, not NULLs
					int twoMinutes = 120000;
					if (alertFilled.IsEntryAlert) {
						// there must be SL.OrderFollowed!=null and TP.OrderFollowed!=null
						if (proto.StopLossAlertForAnnihilation.OrderFollowed == null) {
							string msg = "StopLossAlert.OrderFollowed is NULL!!! engaging ManualResetEvent.WaitOne()";
							this.PopupException(msg);
							Stopwatch waitedForStopLossOrder = new Stopwatch();
							waitedForStopLossOrder.Start();
							proto.StopLossAlertForAnnihilation.MreOrderFollowedIsNotNull.WaitOne(twoMinutes);
							waitedForStopLossOrder.Stop();
							msg = "waited " + waitedForStopLossOrder.ElapsedMilliseconds + "ms for StopLossAlert.OrderFollowed";
							if (proto.StopLossAlertForAnnihilation.OrderFollowed == null) {
								msg += ": NO_SUCCESS still null!!!";
								this.PopupException(msg);
							} else {
								proto.StopLossAlertForAnnihilation.OrderFollowed.AppendMessage(msg);
								this.PopupException(msg);
							}
						} else {
							string msg = "you are definitely crazy, StopLossAlert.OrderFollowed is a single-threaded assignment";
							//this.ThrowPopup(new Exception(msg));
						}

						if (proto.TakeProfitAlertForAnnihilation.OrderFollowed == null) {
							string msg = "TakeProfitAlert.OrderFollowed is NULL!!! engaging ManualResetEvent.WaitOne()";
							this.PopupException(msg);
							Stopwatch waitedForTakeProfitOrder = new Stopwatch();
							waitedForTakeProfitOrder.Start();
							proto.TakeProfitAlertForAnnihilation.MreOrderFollowedIsNotNull.WaitOne();
							waitedForTakeProfitOrder.Stop();
							msg = "waited " + waitedForTakeProfitOrder.ElapsedMilliseconds + "ms for TakeProfitAlert.OrderFollowed";
							if (proto.TakeProfitAlertForAnnihilation.OrderFollowed == null) {
								msg += ": NO_SUCCESS still null!!!";
								this.PopupException(msg);
							} else {
								proto.TakeProfitAlertForAnnihilation.OrderFollowed.AppendMessage(msg);
								this.PopupException(msg);
							}
						} else {
							string msg = "you are definitely crazy, TakeProfitAlert.OrderFollowed is a single-threaded assignment";
							//this.ThrowPopup(new Exception(msg));
						}
					}
				}
			}

			if (this.Backtester.IsBacktestingNow == false) {
				ReporterPokeUnit pokeUnit = new ReporterPokeUnit(quote);
				pokeUnit.AlertsNew = alertsNewAfterAlertFilled;
				pokeUnit.PositionsOpened = positionsOpenedAfterAlertFilled;
				pokeUnit.PositionsClosed = positionsClosedAfterAlertFilled;
				this.PushPositionsOpenedClosedToReportersAsyncUnsafe(pokeUnit);
			}

			// 4. Script event will generate a StopLossMove PostponedHook
			this.invokeScriptEvents(alertFilled);

			// reasons for (alertsNewAfterExec.Count > 0) include:
			// 2.1. PrototypeActivator::AlertFilledPlaceSlTpOrAnnihilateCounterparty
			// 2.2. Script.OnAlertFilledCallback(alert)
			// 2.3. Script.OnPositionOpenedPrototypeSlTpPlacedCallback(alert.PositionAffected)
			// 2.4. Script.OnPositionClosedCallback(alert.PositionAffected)
		}