public Alert ExitAlertCreate(Bar exitBar, Position position, double stopOrLimitPrice, string signalName, Direction direction, MarketLimitStop exitMarketLimitStop) { this.checkThrowEntryBarIsValid(exitBar); this.checkThrowPositionToCloseIsValid(position); double priceScriptOrStreaming = stopOrLimitPrice; OrderSpreadSide orderSpreadSide = OrderSpreadSide.Unknown; if (exitMarketLimitStop == MarketLimitStop.Market) { priceScriptOrStreaming = this.getStreamingPriceForMarketOrder(exitMarketLimitStop, direction, out orderSpreadSide); } PositionLongShort longShortFromDirection = MarketConverter.LongShortFromDirection(direction); double exitPriceScript = exitBar.ParentBars.SymbolInfo.RoundAlertPriceToPriceLevel( priceScriptOrStreaming, true, longShortFromDirection, exitMarketLimitStop); Alert alert = new Alert(exitBar, position.Shares, exitPriceScript, signalName, direction, exitMarketLimitStop, orderSpreadSide, //this.executor.Script, this.executor.Strategy); alert.AbsorbFromExecutor(executor); alert.PositionAffected = position; // moved to CallbackAlertFilled - we can exit by TP or SL - and position has no clue which Alert was filled!!! //position.ExitCopyFromAlert(alert); alert.PositionAffected.ExitAlertAttach(alert); return alert; }
public Alert EntryAlertCreate(Bar entryBar, double stopOrLimitPrice, string entrySignalName, Direction direction, MarketLimitStop entryMarketLimitStop) { this.checkThrowEntryBarIsValid(entryBar); double priceScriptOrStreaming = stopOrLimitPrice; OrderSpreadSide orderSpreadSide = OrderSpreadSide.Unknown; if (entryMarketLimitStop == MarketLimitStop.Market) { priceScriptOrStreaming = this.getStreamingPriceForMarketOrder(entryMarketLimitStop, direction, out orderSpreadSide); } PositionLongShort longShortFromDirection = MarketConverter.LongShortFromDirection(direction); // ALREADY_ALIGNED_AFTER GetAlignedBidOrAskForTidalOrCrossMarketFromStreaming double entryPriceScript = entryBar.ParentBars.SymbolInfo.RoundAlertPriceToPriceLevel( priceScriptOrStreaming, true, longShortFromDirection, entryMarketLimitStop); double shares = this.executor.PositionSizeCalculate(entryBar, entryPriceScript); Alert alert = new Alert(entryBar, shares, entryPriceScript, entrySignalName, direction, entryMarketLimitStop, orderSpreadSide, //this.executor.Script, this.executor.Strategy); alert.AbsorbFromExecutor(executor); return alert; }
public override void SelectAlert(Alert alert) { this.ActivateParentForm(); if (alert == null) { string msg = "DONT_PASS_ALERT=NULL_TO_CHART_SHADOW ChartControl.SelectAlert()"; Assembler.PopupException(msg); #if DEBUG Debugger.Break(); #endif return; } if (alert.PlacedBar == null) { string msg = "DONT_PASS_ALERT.PLACEDBAR=NULL_TO_CHART_SHADOW ChartControl.SelectAlert()"; Assembler.PopupException(msg); #if DEBUG Debugger.Break(); #endif return; } if (alert.PlacedBar.HasParentBars == false) { string msg = "DONT_PASS_ALERT.PLACEDBAR.HASPARENTBARS=FALSE_TO_CHART_SHADOW ChartControl.SelectAlert()"; Assembler.PopupException(msg); #if DEBUG Debugger.Break(); #endif return; } int bar = alert.PlacedBar.ParentBarsIndex; this.scrollToBarSafely(bar); }
public bool SimulateFill(Alert alert, out bool abortTryFill, out string abortTryFillReason) { abortTryFill = false; abortTryFillReason = "ABORT_NO_REASON_SO_SHOULD_CONTINUE_TRY_FILL"; if (alert.DataSource.BrokerProviderName.Contains("Mock") == false) { string msg = "SimulateRealtimeOrderFill() should be called only from BrokerProvidersName.Contains(Mock)" + "; here you have MOCK Realtime Streaming and Broker," + " it's not a time-insensitive QuotesFromBar-generated Streaming Backtest" + " (both are routed to here, MarketSim, hypothetical order execution)"; throw new Exception(msg); } if (alert.PositionAffected == null) { string msg = "alertToBeKilled always has a PositionAffected, even for OnChartManual Buy/Short Market/Stop/Limit"; throw new Exception(msg); } bool filled = false; double priceFill = -1; double slippageFill = -1; Quote quote = this.executor.DataSource.StreamingProvider.StreamingDataSnapshot.LastQuoteGetForSymbol(alert.Symbol); if (quote == null) { string msg = "how come LastQuoteGetForSymbol(" + alert.Symbol + ")=null??? StreamingProvider[" + this.executor.DataSource.StreamingProvider + "]"; //this.executor.PopupException(new Exception(msg)); return false; } if (alert.IsEntryAlert) { if (alert.PositionAffected.IsEntryFilled) { string msg = "PositionAffected.EntryFilled => did you create many threads in your QuikTerminalMock?"; throw new Exception(msg); } filled = this.CheckEntryAlertWillBeFilledByQuote(alert, quote, out priceFill, out slippageFill); } else { if (alert.PositionAffected.IsEntryFilled == false) { string msg = "I refuse to tryFill an ExitOrder because ExitOrder.Alert.PositionAffected.EntryFilled=false"; throw new Exception(msg); } if (alert.PositionAffected.IsExitFilled) { string msg = null; if (alert.PositionAffected.IsExitFilledWithPrototypedAlert) { msg = "ExitAlert already filled and Counterparty.Status=[" + alert.PositionAffected.PrototypedExitCounterpartyAlert.OrderFollowed.State + "] (does it look OK for you?)"; } else { msg = "I refuse to tryFill non-Prototype based ExitOrder having PositionAffected.IsExitFilled=true"; } abortTryFill = true; abortTryFillReason = msg; // abortTryFillReason goes to the order.Message inside the caller //this.executor.ThrowPopup(new Exception(msg)); return false; } try { filled = this.CheckExitAlertWillBeFilledByQuote(alert, quote, out priceFill, out slippageFill); } catch (Exception e) { int a = 1; } } return filled; }
bool checkIfAlertDoesntHaveAnArrow(List<AlertArrow> alertArrowsSameBar, Alert alert) { Alert mustBeNull = null; foreach (AlertArrow each in alertArrowsSameBar) { Alert alertSameDirection = each.ArrowIsForPositionEntry ? each.Position.EntryAlert : each.Position.ExitAlert; if (alertSameDirection != alert) continue; mustBeNull = alertSameDirection; break; } if (mustBeNull != null) { string msg = "DUPLICATE_ALERTARROW mustBeNull=[" + mustBeNull + "])"; Assembler.PopupException(msg); } return mustBeNull == null; }
public static Brush AlertPendingToBrushColor(Alert alert) { Brush brush = Brushes.Black; switch (alert.Direction) { case Direction.Buy: brush = Brushes.Blue; break; case Direction.Sell: brush = Brushes.Red; break; case Direction.Short: brush = Brushes.Fuchsia; break; case Direction.Cover: brush = Brushes.Green; break; } return brush; }
public Order CreatePropagateOrderFromAlert(Alert alert, bool setStatusSubmitting, bool fromAutoTrading) { if (alert.MarketLimitStop == MarketLimitStop.AtClose) { string msg = "NYI: alert.OrderType= OrderType.AtClose [" + alert + "]"; throw new Exception(msg); } Order newborn = new Order(alert, fromAutoTrading, false); try { newborn.Alert.DataSource.BrokerProvider.ModifyOrderTypeAccordingToMarketOrderAs(newborn); } catch (Exception e) { string msg = "hoping that MarketOrderAs.MarketMinMax influenced order.Alert.MarketLimitStop[" + newborn.Alert.MarketLimitStop + "]=MarketLimitStop.Limit for further match; PREV=" + newborn.LastMessage; this.AppendOrderMessageAndPropagateCheckThrowOrderNull(newborn, msg); } if (alert.IsExitAlert) { if (this.isExitOrderConsistentLogInconsistency(newborn) == false) { this.DataSnapshot.OrderAddSynchronizedAndPropagate(newborn); string reason = newborn.LastMessage; return null; } //adjustExitOrderQtyRequestedToMatchEntry(order); alert.PositionAffected.EntryAlert.OrderFollowed.DerivedOrdersAdd(newborn); } OrderState newbornOrderState = OrderState.AutoSubmitNotEnabled; string newbornMessage = "alert[" + alert + "]"; if (setStatusSubmitting == true) { if (newborn.hasBrokerProvider("CreatePropagateOrderFromAlert(): ") == false) { string msg = "CRAZY #61"; Assembler.PopupException(msg); return null; } newbornOrderState = this.IsOrderEatable(newborn) ? OrderState.Submitting : OrderState.ErrorSubmittingNotEatable; //string isPastDue = newborn.Alert.IsAlertCreatedOnPreviousBar; //if (fromAutoTrading && String.IsNullOrEmpty(isPastDue) == false) { // newbornMessage += "; " + isPastDue; // newbornOrderState = OrderState.AlertCreatedOnPreviousBarNotAutoSubmitted; //} } this.UpdateOrderStateNoPostProcess(newborn, new OrderStateMessage(newborn, newbornOrderState, newbornMessage)); this.DataSnapshot.OrderAddSynchronizedAndPropagate(newborn); this.DataSnapshot.SerializerLogrotateOrders.HasChangesToSave = true; return newborn; }
public List<Alert> AlertFilledCreateSlTpOrAnnihilateCounterparty(Alert alert) { List<Alert> ret = new List<Alert>(); if (alert.PositionAffected == null) return ret; if (alert.PositionAffected.Prototype == null) return ret; if (alert.IsEntryAlert) { return this.CreateStopLossAndTakeProfitAlertsFromPositionPrototype(alert.PositionAffected); } else { bool killed = this.AnnihilateCounterpartyForClosedPosition(alert.PositionAffected); return ret; } }
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) }
public Position(Alert alertEntry, double basisPrice) : this(alertEntry.Bars , alertEntry.PositionLongShortFromDirection, alertEntry.StrategyID.ToString() , basisPrice, alertEntry.Qty) { this.EntryAlert = alertEntry; this.EntryMarketLimitStop = alertEntry.MarketLimitStop; this.EntryPriceScript = alertEntry.PriceScript; this.EntrySignal = alertEntry.SignalName; }
public void ExitAlertAttach(Alert alertExit) { if (this.Prototype == null) { if (this.ExitAlert != null) { string msg = "POSITION_WAS_ALREADY_ATTCHED_TO_EXIT_ALERT ExitAlert[" + this.ExitAlert + "] "; throw new Exception(msg); } if (this.ExitMarketLimitStop != MarketLimitStop.Unknown) { string msg = "POSITION_WAS_ALREADY_SYNCHED_WITH_FILLED_ALERT_ON_ALERT_FILLED_CALLBACK: ExitPriceScript[" + this.ExitPriceScript + "]"; throw new Exception(msg); } } else { if (this.ExitAlert != null) { if (alertExit.IsFilled == false) { string msg = "REPLACING_FIRST_CREATED_STOPLOSS_WITH_SECOND_CREATED_TAKEPROFIT ExitAlert[" + this.ExitAlert.SignalName + "] shouldBeTakeprofit[" + alertExit.SignalName + "]"; } else { string msg = "REPLACING_EXIT_ALERT_WITH_PROTOTYPED_TP_OR_SL_WHICHEVER_FILLED_FIRST ExitAlert[" + this.ExitAlert + "] filledFirst[" + alertExit + "]"; } } } this.ExitAlert = alertExit; this.ExitMarketLimitStop = alertExit.MarketLimitStop; this.ExitPriceScript = alertExit.PriceScript; this.ExitSignal = alertExit.SignalName; }
public void RemovePendingExitAlert(Alert alert, string msig) { string msg = ""; ExecutionDataSnapshot snap = alert.Strategy.Script.Executor.ExecutionDataSnapshot; //this.executor.ExecutionDataSnapshot.AlertsPendingRemove(alert); string orderState = (alert.OrderFollowed == null) ? "alert.OrderFollowed=NULL" : alert.OrderFollowed.State.ToString(); if (snap.AlertsPendingContains(alert)) { bool removed = snap.AlertsPendingRemove(alert); msg = "REMOVED " + orderState + " Pending alert[" + alert + "] "; } else { msg = "CANT_BE_REMOVED " + orderState + " isn't Pending alert[" + alert + "] "; } if (alert.OrderFollowed == null) { if (this.Backtester.IsBacktestingNow == false) { msg = "RealTime alerts should NOT have OrderFollowed=null; " + msg; throw new Exception(msg); } return; } // OrderFollowed=null when executeStrategyBacktestEntryPoint() is in the call stack this.OrderProcessor.AppendOrderMessageAndPropagateCheckThrowOrderNull(alert.OrderFollowed, msig + msg); }
public void AlertKillPending(Alert alert) { this.Executor.AlertKillPending(alert); }
public override void OnAlertNotSubmittedCallback(Alert alertNotSubmitted, int barNotSubmittedRelno) { Debugger.Break(); }
public void CreatedOrderWontBePlacedPastDueInvokeScript(Alert alert, int barNotSubmittedRelno) { //this.ExecutionDataSnapshot.AlertsPendingRemove(alert); if (alert.IsEntryAlert) { this.RemovePendingEntry(alert); this.ClosePositionWithAlertClonedFromEntryBacktestEnded(alert); } else { string msg = "checkPositionCanBeClosed() will later interrupt the flow saying {Sorry I don't serve alerts.IsExitAlert=true}"; this.RemovePendingExitAlertPastDueClosePosition(alert); } if (this.Strategy.Script == null) return; try { this.Strategy.Script.OnAlertNotSubmittedCallback(alert, barNotSubmittedRelno); } catch (Exception e) { string msg = "fix your OnAlertNotSubmittedCallback() in script[" + this.Strategy.Script.StrategyName + "]" + "; was invoked with alert[" + alert + "] and barNotSubmittedRelno[" + barNotSubmittedRelno + "]"; this.PopupException(msg, e); } }
public static BidOrAsk BidOrAskWillFillAlert(Alert alert) { BidOrAsk ret = BidOrAsk.UNKNOWN; switch (alert.MarketLimitStop) { case MarketLimitStop.Market: case MarketLimitStop.Limit: switch (alert.Direction) { //http://www.metatrader5.com/en/terminal/help/trading/general_concept/order_types case Direction.Short: case Direction.Sell: ret = BidOrAsk.Bid; break; case Direction.Buy: case Direction.Cover: ret = BidOrAsk.Ask; break; default: throw new Exception("BidOrAskWillFillAlert(): NYI direction[" + alert.Direction + "] for [" + alert + "]"); } break; case MarketLimitStop.Stop: case MarketLimitStop.StopLimit: switch (alert.Direction) { //http://www.metatrader5.com/en/terminal/help/trading/general_concept/order_types case Direction.Short: case Direction.Sell: ret = BidOrAsk.Bid; break; case Direction.Buy: case Direction.Cover: ret = BidOrAsk.Ask; break; default: throw new Exception("BidOrAskWillFillAlert(): NYI direction[" + alert.Direction + "] for [" + alert + "]"); } break; } return ret; }
public override void OnAlertFilledCallback(Alert alertFilled) { if (alertFilled.IsExitAlert) return; Position position = alertFilled.PositionAffected; }
public void AlertKillPending(Alert alert) { if (this.Backtester.IsBacktestingNow) { this.MarketSimStreaming.SimulateAlertKillPending(alert); } else { this.MarketRealStreaming.AlertKillPending(alert); } }
private bool checkPositionCanBeClosed(Alert alert, string msig, bool checkPositionOpenNow = true) { if (alert.PositionAffected == null) { string msg = "can't close PositionAffected and remove Position from PositionsOpenNow" + ": alert.PositionAffected=null for alert [" + alert + "]"; //throw new Exception(msig + msg); this.OrderProcessor.AppendOrderMessageAndPropagateCheckThrowOrderNull(alert.OrderFollowed, msig + msg); return false; } if (alert.IsExitAlert) { string msg = "Sorry I don't serve alerts.IsExitAlert=true, only .IsEntryAlert's: alert [" + alert + "]"; //throw new Exception(msig + msg); this.OrderProcessor.AppendOrderMessageAndPropagateCheckThrowOrderNull(alert.OrderFollowed, msig + msg); return false; } if (checkPositionOpenNow == true) { bool shouldRemove = this.ExecutionDataSnapshot.HasPositionOpenNow(alert.PositionAffected); if (alert.FilledBarIndex > -1) { if (shouldRemove) { int a = 1; } string msg = "CHECK_POSITION_OPEN_NOW Sorry I serve only BarRelnoFilled==-1" + " otherwize alert.FillPositionAffectedEntryOrExitRespectively() with throw: alert [" + alert + "]"; this.OrderProcessor.AppendOrderMessageAndPropagateCheckThrowOrderNull(alert.OrderFollowed, msig + msg); return false; } if (alert.PositionAffected.ExitFilledBarIndex > -1) { if (shouldRemove) { int a = 1; } string msg = "CHECK_POSITION_OPEN_NOW Sorry I serve only alert.PositionAffected.ExitBar==-1" + " otherwize PositionAffected.FillExitAlert() will throw: alert [" + alert + "]"; this.OrderProcessor.AppendOrderMessageAndPropagateCheckThrowOrderNull(alert.OrderFollowed, msig + msg); return false; } } else { Bar barFill = (this.IsStreaming) ? alert.Bars.BarStreamingCloneReadonly : alert.Bars.BarStaticLast; if (alert.PositionAffected.EntryFilledBarIndex != -1) { string msg = "DUPE: can't do my job: alert.PositionAffected.EntryBar!=-1 for alert [" + alert + "]"; //throw new Exception(msig + msg); this.OrderProcessor.AppendOrderMessageAndPropagateCheckThrowOrderNull(alert.OrderFollowed, msig + msg); //return; } else { string msg = "Forcibly closing at EntryBar=[" + barFill + "]"; this.OrderProcessor.AppendOrderMessageAndPropagateCheckThrowOrderNull(alert.OrderFollowed, msig + msg); } } return true; }
public void ClosePositionWithAlertClonedFromEntryBacktestEnded(Alert alert) { string msig = " ClosePositionWithAlertClonedFromEntryBacktestEnded():"; this.RemovePendingExitAlert(alert, msig); bool checkPositionOpenNow = true; if (this.checkPositionCanBeClosed(alert, msig, checkPositionOpenNow) == false) return; if (alert.FilledBar == null) { string msg = "BACKTEST_ENDED_ALERT_UNFILLED strategy[" + this.Strategy.ToString() + "] alert[" + alert + "]"; Assembler.PopupException(msg + msig); return; } //Alert alertExitClonedStub = alert.CloneToRefactor(); //alertExitClonedStub.SignalName += " ClosePositionWithAlertClonedFromEntryBacktestEnded Forced"; //alertExitClonedStub.Direction = MarketConverter.ExitDirectionFromLongShort(alert.PositionLongShortFromDirection); //// 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(alertExitClonedStub); alert.PositionAffected.FillExitWith(alert.FilledBar, alert.PriceScript, alert.Qty, 0, 0); //alertFilled.FillPositionAffectedEntryOrExitRespectively(barFill, barFillRelno, priceFill, qtyFill, slippageFill, commissionFill); bool absenseInPositionsOpenNowIsAnError = false; 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 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 override void OnAlertKilledCallback(Alert alertKilled) { //Debugger.Break(); }
public void CallbackAlertKilledInvokeScript(Alert alert) { if (this.ExecutionDataSnapshot.AlertsPendingContains(alert) == false) { string msg = "Alert wasn't found in snap.AlertsPending"; throw new Exception(msg); } bool removed = this.ExecutionDataSnapshot.AlertsPendingRemove(alert); alert.Strategy.Script.OnAlertKilledCallback(alert); }
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; }
public virtual void OnAlertNotSubmittedCallback(Alert alertNotSubmitted, int barNotSubmittedRelno) { }
public bool AlertKillPending(Alert alert) { throw new NotImplementedException(); }
void invokeScriptEvents(Alert alert) { if (this.Strategy.Script == null) return; try { this.Strategy.Script.OnAlertFilledCallback(alert); } catch (Exception e) { string msg = "fix your OnAlertFilledCallback() in script[" + this.Strategy.Script.StrategyName + "]" + "; was invoked with alert[" + alert + "]"; this.PopupException(msg, e); } if (alert.IsEntryAlert) { try { if (alert.PositionAffected.Prototype != null) { this.Strategy.Script.OnPositionOpenedPrototypeSlTpPlacedCallback(alert.PositionAffected); } else { this.Strategy.Script.OnPositionOpenedCallback(alert.PositionAffected); } } catch (Exception e) { string msg = "fix your ExecuteOnPositionOpened() in script[" + this.Strategy.Script.StrategyName + "]" + "; was invoked with PositionAffected[" + alert.PositionAffected + "]"; this.PopupException(msg, e); } } else { try { this.Strategy.Script.OnPositionClosedCallback(alert.PositionAffected); } catch (Exception e) { string msg = "fix your OnPositionClosedCallback() in script[" + this.Strategy.Script.StrategyName + "]" + "; was invoked with PositionAffected[" + alert.PositionAffected + "]"; this.PopupException(msg, e); } } }
Quote modelQuoteThatCouldFillAlert(Alert alert) { string err; Quote quoteModel = new Quote(); quoteModel.Source = "GENERATED_TO_FILL_" + alert.ToString(); quoteModel.Size = alert.Qty; double priceScriptAligned = this.backtester.Executor.AlignAlertPriceToPriceLevel(alert.Bars, alert.PriceScript, true, alert.PositionLongShortFromDirection, alert.MarketLimitStop); Quote quotePrev = this.backtester.BacktestDataSource.BacktestStreamingProvider.StreamingDataSnapshot .LastQuoteGetForSymbol(alert.Symbol); switch (alert.MarketLimitStop) { case MarketLimitStop.Limit: switch (alert.Direction) { case Direction.Buy: case Direction.Cover: if (priceScriptAligned > quotePrev.Ask) { err = "INVALID_PRICESCRIPT_FOR_LIMIT_BUY_MUST_NOT_BE_ABOVE_CURRENT_ASK"; return null; } this.backtester.BacktestDataSource.BacktestStreamingProvider.SpreadModeler .GenerateFillBidBasedOnAsk(quoteModel, priceScriptAligned); break; case Direction.Short: case Direction.Sell: if (priceScriptAligned < quotePrev.Bid) { err = "INVALID_PRICESCRIPT_FOR_LIMIT_SELL_MUST_NOT_BE_BELOW_CURRENT_BID"; return null; } this.backtester.BacktestDataSource.BacktestStreamingProvider.SpreadModeler .GenerateFillAskBasedOnBid(quoteModel, priceScriptAligned); break; default: throw new Exception("ALERT_LIMIT_DIRECTION_UNKNOWN direction[" + alert.Direction + "] is not Buy/Cover/Short/Sell modelQuoteThatCouldFillAlert()"); } break; case MarketLimitStop.Stop: switch (alert.Direction) { case Direction.Buy: case Direction.Cover: if (priceScriptAligned < quotePrev.Ask) { err = "INVALID_PRICESCRIPT_FOR_STOP_BUY_MUST_NOT_BE_BELOW_CURRENT_ASK"; return null; } this.backtester.BacktestDataSource.BacktestStreamingProvider.SpreadModeler .GenerateFillBidBasedOnAsk(quoteModel, priceScriptAligned); break; case Direction.Short: case Direction.Sell: if (priceScriptAligned > quotePrev.Bid) { err = "INVALID_PRICESCRIPT_FOR_STOP_SELL_MUST_NOT_BE_ABOVE_CURRENT_BID"; return null; } this.backtester.BacktestDataSource.BacktestStreamingProvider.SpreadModeler .GenerateFillAskBasedOnBid(quoteModel, priceScriptAligned); break; default: throw new Exception("ALERT_STOP_DIRECTION_UNKNOWN direction[" + alert.Direction + "] is not Buy/Cover/Short/Sell modelQuoteThatCouldFillAlert()"); } break; case MarketLimitStop.Market: switch (alert.Direction) { case Direction.Buy: case Direction.Cover: quoteModel.Ask = quotePrev.Ask; this.backtester.BacktestDataSource.BacktestStreamingProvider.SpreadModeler .GenerateFillBidBasedOnAsk(quoteModel, quotePrev.Ask); break; case Direction.Short: case Direction.Sell: quoteModel.Bid = quotePrev.Bid; this.backtester.BacktestDataSource.BacktestStreamingProvider.SpreadModeler .GenerateFillAskBasedOnBid(quoteModel, quotePrev.Bid); break; default: throw new Exception("ALERT_MARKET_DIRECTION_UNKNOWN direction[" + alert.Direction + "] is not Buy/Cover/Short/Sell modelQuoteThatCouldFillAlert()"); } break; case MarketLimitStop.StopLimit: // HACK one quote might satisfy SLactivation, the other one might fill it; time to introduce state of SL into Alert??? string msg = "STOP_LIMIT_QUOTE_FILLING_GENERATION_REQUIRES_TWO_STEPS_NYI" + "; pass SLActivation=0 to PositionPrototypeActivator so that it generates STOP instead of STOPLOSS which I can't generate yet"; //Debugger.Break(); break; case MarketLimitStop.AtClose: default: throw new Exception("ALERT_TYPE_UNKNOWN MarketLimitStop[" + alert.MarketLimitStop + "] is not Market/Limit/Stop modelQuoteThatCouldFillAlert()"); } return quoteModel; }
public virtual void OnAlertKilledCallback(Alert alertKilled) { }