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) }