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; }
internal void PositionsMasterOpenNewAdd(Position positionOpening) { if (positionOpening.EntryFilledBarIndex == -1) { string msg = "ENTRY_BAR_NEGATIVE_CAN_NOT_STORE_POSITION_IN_PositionsMasterByEntryBar" + " Strategy[" + this.executor.Strategy.ToString() + "] EntryBar=-1 for position[" + positionOpening + "]"; #if DEBUG Debugger.Break(); #endif //throw new Exception(msg); this.executor.PopupException(msg); return; } //if (positionOpening.EntryFilledBarIndex < 10) { int a = 1; } lock (this.PositionsMasterByEntryBarLock) { //if (PositionsMasterContainsIdenticalPosition(position)) return; //position.SernoInMasterList = this.PositionsMaster.Count; List<Position> sameBarPositions = null; if (this.PositionsMasterByEntryBar.ContainsKey(positionOpening.EntryFilledBarIndex) == false) { sameBarPositions = new List<Position>(); this.PositionsMasterByEntryBar.Add(positionOpening.EntryFilledBarIndex, sameBarPositions); } else { sameBarPositions = this.PositionsMasterByEntryBar[positionOpening.EntryFilledBarIndex]; //foreach (Position each in sameBarPositions) { // if (position == each) {int a = 1;} // if (position.Equals(each)) { int b = 2; } //} bool brokerDupe = sameBarPositions.Contains(positionOpening); // see Position.Equals() if (brokerDupe) { string msg = "positionOpening already added everywhere; create a dupe-filtering! " + positionOpening; this.executor.PopupException(msg); return; } } positionOpening.SernoAbs = ++this.positionSernoAbs; sameBarPositions.Add(positionOpening); if (this.PositionsMaster.Contains(positionOpening)) { string msg = "position is already in PositionsMaster, won't add a dupe; create a dupe-filtering!"; this.executor.PopupException(msg); } else { this.PositionsMaster.Add(positionOpening); } if (this.PositionsOpenedAfterExec.Contains(positionOpening)) { string msg = "position is already in PositionsOpenedAfterExec, won't add a dupe; create a dupe-filtering!"; this.executor.PopupException(msg); } else { this.PositionsOpenedAfterExec.Add(positionOpening); } if (this.PositionsOpenNow.Contains(positionOpening)) { string msg = "position is already in PositionsOpenNow, won't add a dupe; create a dupe-filtering!"; this.executor.PopupException(msg); } else { this.PositionsOpenNow.Add(positionOpening); } } }
public List<Alert> CreateStopLossAndTakeProfitAlertsFromPositionPrototype(Position position) { if (position.IsEntryFilled == false) { string msg = "I can not place SL and TP for an unopened position; alert[" + position.EntryAlert + "]"; throw new Exception(msg); } Alert SlPlaced = this.CreateStopLossFromPositionPrototype(position); Alert TpPlaced = this.CreateTakeProfitFromPositionPrototype(position); return new List<Alert>() { SlPlaced, TpPlaced }; }
private void checkThrowPositionToCloseIsValid(Position position) { if (position == null) { string msg = "position=null, can't close it!"; throw new Exception(msg); } if (position.NoExitBarOrStreaming == false) { string msg = "position.Active=false, can't close it!"; throw new Exception(msg); } }
private bool checkPendingEntryPositionAlreadyPlaced(Position entryPosition) { if (entryPosition.EntryAlert == null) return false; foreach (Alert alert in executor.ExecutionDataSnapshot.AlertsPending) { Position pos = alert.PositionAffected; if (pos == null) continue; if (pos.EntryAlert == null) continue; if (pos.EntryAlert == entryPosition.EntryAlert) return true; if (pos.EntryAlert.IsIdenticalForOrdersPending(entryPosition.EntryAlert)) return true; } return false; }
public override void SelectPosition(Position position) { this.ActivateParentForm(); if (position == null) { string msg = "DONT_PASS_NULL_POSITION_TO_CHART_SHADOW ChartControl.SelectPosition()"; Assembler.PopupException(msg); #if DEBUG Debugger.Break(); #endif return; } int bar = (position.ExitAlert != null) ? position.ExitAlert.PlacedBar.ParentBarsIndex : position.EntryAlert.PlacedBar.ParentBarsIndex; this.scrollToBarSafely(bar); }
public Alert CreateStopLossFromPositionPrototype(Position position) { //if (this.executor.checkPrototypeAlreadyPlaced(position)) return; PositionPrototype proto = position.Prototype; if (proto.StopLossNegativeOffset == 0) { string msg = "What should Activator do with proto.StopLossNegativeOffset=0?"; throw new Exception(msg); } if (proto.StopLossNegativeOffset == 0) { string msg = this.ReasonWhyNewStopLossOffsetDoesntMakeSense(position, proto.StopLossNegativeOffset); if (String.IsNullOrEmpty(msg) == false) { string msg2 = "What should Activator do with sense-less proto.StopLossNegativeOffset[" + proto.StopLossNegativeOffset + "], "; throw new Exception(msg2, new Exception(msg)); } } MarketLimitStop simpleStopIfActivationZero = (proto.StopLossActivationNegativeOffset == 0) ? MarketLimitStop.Stop : MarketLimitStop.StopLimit; Alert alertStopLoss = executor.SellOrCoverAlertCreateDontRegister ( executor.Bars.BarStreaming, position, proto.PriceStopLoss, "protoStopLossExit:" + proto.StopLossActivationNegativeOffset + "@" + proto.StopLossNegativeOffset + " for " + position.EntrySignal, MarketConverter.ExitDirectionFromLongShort(proto.LongShort), simpleStopIfActivationZero); if (alertStopLoss == null) { string msg = "alertStopLoss should NOT be null"; throw new Exception(msg); } alertStopLoss.PriceStopLimitActivation = 0; if (proto.StopLossActivationNegativeOffset < 0) alertStopLoss.PriceStopLimitActivation = proto.PriceStopLossActivation; if (proto.StopLossAlertForAnnihilation != null && this.executor.Backtester.IsBacktestingNow == false) { string msg = "CLEANUP: I was trying to catch MoveStopLoss::if(proto.StopLossAlertForAnnihilation==null)" + " so I thought there is a new prototype assigned to a position," + " since we never put null directly proto.StopLossAlertForAnnihilation"; throw new Exception(msg); } proto.StopLossAlertForAnnihilation = alertStopLoss; return alertStopLoss; }
public override void OnPositionOpenedPrototypeSlTpPlacedCallback(Position positionOpenedProto) { PositionPrototype proto = positionOpenedProto.Prototype; if (proto == null) return; double currentStopLossNegativeOffset = proto.StopLossNegativeOffset; double newStopLossNegativeOffset = currentStopLossNegativeOffset - 20; //string msg = base.Executor.PositionPrototypeActivator.ReasonWhyNewStopLossOffsetDoesntMakeSense(positionOpenedProto, newStopLossNegativeOffset); //if (String.IsNullOrEmpty(msg)) { base.Executor.PositionPrototypeActivator.StopLossNewNegativeOffsetUpdateActivate(positionOpenedProto, newStopLossNegativeOffset); //} else { // base.Executor.PopupException(new Exception("WONT_UPDATE_STOPLOSS: " + msg)); //} double newTakeProfitPositiveOffset = proto.TakeProfitPositiveOffset + 50; //msg = base.Executor.PositionPrototypeActivator.ReasonWhyNewTakeProfitOffsetDoesntMakeSense(positionOpenedProto, newTakeProfitPositiveOffset); //if (String.IsNullOrEmpty(msg)) { base.Executor.PositionPrototypeActivator.TakeProfitNewPositiveOffsetUpdateActivate(positionOpenedProto, newTakeProfitPositiveOffset); //} else { // base.Executor.PopupException(new Exception("WONT_UPDATE_TAKEPROFIT: " + msg)); //} }
public AlertArrow(Position position, bool arrowIsForPositionEntry) { this.Position = position; this.ArrowIsForPositionEntry = arrowIsForPositionEntry; this.Ytransient = 0; this.XBarMiddle = 99; //this.Location = new Point(0, 0); }
public Alert SellAtLimit(Bar bar, Position position, double limitPrice, string signalName = "SOLD_AT_LIMIT") { return this.Executor.SellOrCoverAlertCreateRegister(bar, position, limitPrice, signalName, Direction.Sell, MarketLimitStop.Limit); }
public Alert ExitAtMarket(Bar bar, Position position, string signalName = "EXITED_AT_MARKET") { if (position.PositionLongShort == PositionLongShort.Long) { return this.SellAtMarket(bar, position, signalName); } else { return this.CoverAtMarket(bar, position, signalName); } }
public string ReasonWhyNewTakeProfitOffsetDoesntMakeSense(Position position, double newTakeProfitPositiveOffset, bool internalCallee = false) { PositionPrototype proto = position.Prototype; if (position.Symbol != proto.Symbol) { string msg1 = "NotYetImplemented: your script changes TakeProfitOffset for a proto.Symbol[" + proto.Symbol + "]!=position.Symbol[" + position.Symbol + "]"; throw new Exception(msg1); } Direction dir = MarketConverter.EntryDirectionFromLongShort(proto.LongShort); if (position.EntryAlert.Direction != dir) { string msg1 = "NotYetImplemented: Crazy check here"; throw new Exception(msg1); } Quote quote = executor.DataSource.StreamingProvider.StreamingDataSnapshot.LastQuoteGetForSymbol(proto.Symbol); double priceBestBidAsk = executor.DataSource.StreamingProvider.StreamingDataSnapshot.BidOrAskFor(proto.Symbol, proto.LongShort); double newTakeProfitPrice = proto.OffsetToPrice(newTakeProfitPositiveOffset); bool willBeExecutedImmediately = false; string ident = "TakeProfit{old[" + proto.PriceTakeProfit + "]:new[" + newTakeProfitPrice + "]}"; string msg = ""; switch (dir) { case Direction.Buy: if (newTakeProfitPrice < priceBestBidAsk) { willBeExecutedImmediately = true; msg = "will be filled immediately: newLongTakeProfitPrice[" + newTakeProfitPrice + "] < Ask[" + priceBestBidAsk + "] " + ident + " //position[" + position + "]"; } break; case Direction.Short: if (newTakeProfitPrice > priceBestBidAsk) { willBeExecutedImmediately = true; msg = "will be filled immediately: newShortTakeProfitPrice[" + newTakeProfitPrice + "] > Bid[" + priceBestBidAsk + "] " + ident + " //position[" + position + "]"; } break; default: msg = "I refuse to change TakeProfit when position.EntryAlert.Direction=[" + position.EntryAlert.Direction + "] - must be Buy or Sell only!!!"; break; } if (internalCallee == true) { msg += " (Script is strongly recommented to check TP price first so we don't pass unexpected position closures to the Market)"; } return msg; }
public Alert ExitAtClose(Bar bar, Position position, string signalName = "EXITED_AT_CLOSE") { if (position.PositionLongShort == PositionLongShort.Long) { return this.SellAtClose(bar, position, signalName); } else { return this.CoverAtClose(bar, position, signalName); } }
public List<Alert> PositionCloseImmediately(Position position, string signalName) { this.ExitAtMarket(this.Bars.BarStreaming, position, signalName); // BETTER WOULD BE KILL PREVIOUS PENDING ALERT FROM A CALBACK AFTER MARKET EXIT ORDER GETS FILLED, IT'S UNRELIABLE EXIT IF WE KILL IT HERE // LOOK AT EMERGENCY CLASSES, SOLUTION MIGHT BE THERE ALREADY return this.PositionKillExitAlert(position, signalName); }
public string ReasonWhyNewStopLossOffsetDoesntMakeSense(Position position, double newStopLossNegativeOffset, bool internalCallee = false) { PositionPrototype proto = position.Prototype; if (position.Symbol != proto.Symbol) { string msg1 = "NotYetImplemented: your script changes StopLossOffset for a proto.Symbol[" + proto.Symbol + "]!=position.Symbol[" + position.Symbol + "]"; throw new Exception(msg1); } Direction dir = MarketConverter.EntryDirectionFromLongShort(proto.LongShort); if (position.EntryAlert.Direction != dir) { string msg1 = "NotYetImplemented: Crazy check here"; throw new Exception(msg1); } string msg = ""; double priceBestBidAsk = executor.DataSource.StreamingProvider.StreamingDataSnapshot.BidOrAskFor(proto.Symbol, proto.LongShort); double newStopLossPrice = proto.OffsetToPrice(newStopLossNegativeOffset); switch (proto.StopLossAlertForAnnihilation.MarketLimitStop) { #region StopLimits are considered NYI; mess v1 implementation case MarketLimitStop.StopLimit: double newActivationOffset = proto.CalcActivationOffsetForNewClosing(newStopLossNegativeOffset); //double lastPrice = executor.DataSource.StreamingProvider.StreamingDataSnapshot.LastQuoteGetPriceForMarketOrder(proto.Symbol); //Quote quote = executor.DataSource.StreamingProvider.StreamingDataSnapshot.LastQuoteGetForSymbol(proto.Symbol); double newActivationPrice = proto.OffsetToPrice(newActivationOffset); bool willBeExecutedImmediately = false; string ident = "StopLoss{old[" + proto.PriceStopLoss + "]:new[" + newStopLossPrice + "]}" + " Activation{old[" + proto.PriceStopLossActivation + "]:new[" + newActivationPrice + "]}"; switch (dir) { case Direction.Buy: if (newActivationPrice > priceBestBidAsk) { willBeExecutedImmediately = true; msg = "newActivationPrice[" + newActivationPrice + "] > Bid[" + priceBestBidAsk + "] " + ident + " your SLactivation goes above current price so the StopLoss will be activated/filled immediately..." + " //position[" + position + "]"; } break; case Direction.Short: if (newActivationPrice < priceBestBidAsk) { willBeExecutedImmediately = true; msg = "newActivationPrice[" + newActivationPrice + "] < Ask[" + priceBestBidAsk + "] " + ident + " your SLactivation goes below current price so the StopLoss will be activated/filled immediately..." + " //position[" + position + "]"; } break; default: msg = "I refuse to change StopLoss when position.EntryAlert.Direction=[" + position.EntryAlert.Direction + "] - must be Buy or Short only!!!"; break; } break; #endregion case MarketLimitStop.Stop: string ident2 = "PureStopLoss{old[" + proto.PriceStopLoss + "]:new[" + newStopLossPrice + "]}"; switch (proto.StopLossAlertForAnnihilation.Direction) { case Direction.Sell: double ask = executor.DataSource.StreamingProvider.StreamingDataSnapshot.BestAskGetForMarketOrder(proto.Symbol); if (newStopLossPrice > ask) { msg = "NEW_STOP_PRICE_BELOW_ASK_WILL_BE_REJECTED_BY_MARKET" + " newStopLossPrice[" + newStopLossPrice + "] < Ask[" + ask + "] " + ident2 + " //position[" + position + "]"; } break; case Direction.Cover: double bid = executor.DataSource.StreamingProvider.StreamingDataSnapshot.BestBidGetForMarketOrder(proto.Symbol); if (newStopLossPrice > bid) { msg = "NEW_STOP_PRICE_ABOVE_BID_WILL_BE_REJECTED_BY_MARKET" + " newStopLossPrice[" + newStopLossPrice + "] > Bid[" + bid + "] " + ident2 + " //position[" + position + "]"; } break; default: msg = "PROTOTYPE_BASED_STOP_LOSS_MODIFICATION_REFUSED_MUSTBE_SELL_OR_COVER" + "; position.ExitA.Direction=[" + position.ExitAlert.Direction + "]"; break; } break; default: msg = "STOP_LOSS_ALERT_TYPE_NOT_SUPPORTED [" + proto.StopLossAlertForAnnihilation.MarketLimitStop + "]"; throw new Exception(msg); } if (internalCallee == true) { msg += " (Script is strongly recommented to check SL price first so we don't pass unexpected position closures to the Market)"; } return msg; }
public override void OnPositionClosedCallback(Position positionClosed) { //Debugger.Break(); }
public Alert CoverAtClose(Bar bar, Position position, string signalName = "COVERED_AT_CLOSE") { return this.Executor.SellOrCoverAlertCreateRegister(bar, position, 0, signalName, Direction.Cover, MarketLimitStop.AtClose); }
public bool AnnihilateCounterpartyForClosedPosition(Position position) { bool killed = false; if (position.IsExitFilled == false) { string msg = "I refuse to AnnihilateCounterpartyForClosedPosition: position.IsExitFilled=false for position=[" + position + "]"; throw new Exception(msg); } if (position.Prototype == null) { string msg = "I refuse to AnnihilateCounterpartyForClosedPosition: position.Prototype=null"; throw new Exception(msg); } if (position.IsExitFilledByPrototypedTakeProfit) { if (position.Prototype.StopLossAlertForAnnihilation == null) { string msg = "FAILED_ANNIHILATE_STOPLOSS Prototype.StopLossAlertForAnnihilation=null for position[" + position + "]"; throw new Exception(msg); } killed = executor.AnnihilateCounterpartyAlertDispatched(position.Prototype.StopLossAlertForAnnihilation); if (executor.Backtester.IsBacktestingNow == false) { string msg = "killed[" + killed + "] counterParty [" + position.Prototype.StopLossAlertForAnnihilation + "]"; this.appendMessageToTakeProfitOrder(position, msg); } if (killed == false) { string msg = "position.ClosedByTakeProfit but StopLoss wasn't annihilated" + " or DUPE annihilation of a previously annihilated StopLoss"; throw new Exception(msg); } } if (position.IsExitFilledByPrototypedStopLoss) { if (position.Prototype.TakeProfitAlertForAnnihilation == null) { string msg = "FAILED_ANNIHILATE_TAKEPROFIT Prototype.TakeProfitAlertForAnnihilation=null for position[" + position + "]"; throw new Exception(msg); } killed = executor.AnnihilateCounterpartyAlertDispatched(position.Prototype.TakeProfitAlertForAnnihilation); if (executor.Backtester.IsBacktestingNow == false) { string msg = "killed[" + killed + "] counterParty [" + position.Prototype.TakeProfitAlertForAnnihilation + "]"; this.appendMessageToStopLossOrder(position, msg); } if (killed == false) { string msg = "position.ClosedByStopLoss but TakeProfit wasn't annihilated" + " or DUPE annihilation of a previously annihilated TakeProfit"; throw new Exception(msg); } } return killed; }
void appendMessageToTakeProfitOrder(Position position, string msgOrder) { if (position.Prototype.TakeProfitAlertForAnnihilation == null) { string msg = "Can't AppendMessageToTakeProfitOrder: position.Prototype.TakeProfitAlertForAnnihilation=null"; throw new Exception(msg); } if (position.Prototype.TakeProfitAlertForAnnihilation.OrderFollowed == null) { string msg = "Can't AppendMessageToTakeProfitOrder: position.Prototype.TakeProfitAlertForAnnihilation.OrderFollowed=null"; throw new Exception(msg); } position.Prototype.TakeProfitAlertForAnnihilation.OrderFollowed.AppendMessage(msgOrder); }
public Alert CreateTakeProfitFromPositionPrototype(Position position) { PositionPrototype proto = position.Prototype; if (proto.TakeProfitPositiveOffset == 0) { string msg = "What should Activator do with proto.StopLossNegativeOffset=0?"; throw new Exception(msg); } Alert alertTakeProfit = executor.SellOrCoverAlertCreateDontRegister ( executor.Bars.BarStreaming, position, proto.PriceTakeProfit, "protoTakeProfitExit:" + proto.TakeProfitPositiveOffset + "@" + proto.PriceTakeProfit + " for " + position.EntrySignal, MarketConverter.ExitDirectionFromLongShort(position.Prototype.LongShort), MarketLimitStop.Limit); if (alertTakeProfit == null) { string msg = "alertTakeProfit should NOT be null"; throw new Exception(msg); } proto.TakeProfitAlertForAnnihilation = alertTakeProfit; return alertTakeProfit; }
public bool Equals(Position otherPosition) { bool headerIsTheSame = this.PositionLongShort == otherPosition.PositionLongShort && this.Symbol == otherPosition.Symbol && this.Shares == otherPosition.Shares; if (headerIsTheSame == false) return false; bool entryIsTheSame = this.EntryMarketLimitStop == otherPosition.EntryMarketLimitStop && this.EntryFilledBarIndex == otherPosition.EntryFilledBarIndex && this.EntryFilledPrice == otherPosition.EntryFilledPrice && this.EntrySignal == otherPosition.EntrySignal; if (entryIsTheSame == false) return false; // what did I want to say by this?? //if (this.ExitBar == -1) return true; //if (otherPosition.ExitBar == -1) return true; bool bothNaNs = double.IsNaN(this.ExitFilledPrice) && double.IsNaN(otherPosition.ExitFilledPrice); if (bothNaNs) { bool exitIsTheSameNaNs = this.EntryMarketLimitStop == otherPosition.EntryMarketLimitStop && this.ExitFilledBarIndex == otherPosition.ExitFilledBarIndex && this.ExitSignal == otherPosition.ExitSignal; return exitIsTheSameNaNs; } bool exitIsTheSame = this.EntryMarketLimitStop == otherPosition.EntryMarketLimitStop && this.ExitFilledBarIndex == otherPosition.ExitFilledBarIndex && this.ExitFilledPrice == otherPosition.ExitFilledPrice && this.ExitSignal == otherPosition.ExitSignal; //bool alwaysDifferent = this.SernoInMasterList == position.SernoInMasterList; return exitIsTheSame; }
public List<Alert> PositionKillExitAlert(Position position, string signalName) { List<Alert> alertsSubmittedToKill = new List<Alert>(); if (position.IsEntryFilled == false) { Debugger.Break(); return alertsSubmittedToKill; } if (null == position.ExitAlert) { // for prototyped position, position.ExitAlert contains TakeProfit Debugger.Break(); return alertsSubmittedToKill; } if (string.IsNullOrEmpty(signalName)) signalName = "PositionCloseImmediately()"; if (position.Prototype != null) { alertsSubmittedToKill = this.PositionPrototypeKillWhateverIsPending(position.Prototype, signalName); return alertsSubmittedToKill; } this.AlertKillPending(position.ExitAlert); alertsSubmittedToKill.Add(position.ExitAlert); return alertsSubmittedToKill; }
public override void OnPositionOpenedCallback(Position positionOpened) { // NEVER_INVOKED_SINCE_I_USE_POSITION_PROTOTYPES_ONLY no direct BuyAt* or SellAt* Debugger.Break(); }
public Alert SellAtStop(Bar bar, Position position, double stopPrice, string signalName = "SOLD_AT_STOP") { return this.Executor.SellOrCoverAlertCreateRegister(bar, position, stopPrice, signalName, Direction.Sell, MarketLimitStop.Stop); }
public void TakeProfitNewPositiveOffsetUpdateActivate(Position position, double newTakeProfitPositiveOffset) { PositionPrototype proto = position.Prototype; if (proto == null) { string msg = "TakeProfitNewPositiveOffsetUpdateActivate() can't update TakeProfit for a position.Prototype=null: position=[" + position + "]"; throw new Exception(msg); } this.checkThrowNewTakeProfitOffsetMakesSense(position, newTakeProfitPositiveOffset); //proto.checkOffsetsThrowBeforeAbsorbing(newTakeProfitPositiveOffset, proto.StopLossNegativeOffset, proto.StopLossActivationNegativeOffset); if (executor.Backtester.IsBacktestingNow) { // NOPE!!! I WANT ALL ALERTS TO STAY IN HISTORY!!! just move TP in Alert, change Prices immediately; no orderKill/newOrder for TakeProfit (Alerts don't have OrdersFollowed) // PositionPrototypeActivator.checkThrowNewPriceMakesSense() made sure Alert!=null // TP_WILL_BE_KILLED proto.TakeProfitAlertForAnnihilation.PriceScript = proto.OffsetToPrice(newTakeProfitPositiveOffset); proto.SetNewTakeProfitOffset(newTakeProfitPositiveOffset); // TODO: don't forget about backtesting and MarketSim (implement OppMover for offline) executor.MarketSimStreaming.SimulateTakeProfitMoved(proto.TakeProfitAlertForAnnihilation); } else { executor.DataSource.BrokerProvider.MoveTakeProfitOrderProcessorInvoker(proto, newTakeProfitPositiveOffset); } }
public Alert ExitAtStop(Bar bar, Position position, double price, string signalName = "EXITED_AT_STOP") { if (position.PositionLongShort == PositionLongShort.Long) { return this.SellAtStop(bar, position, price, signalName); } else { return this.CoverAtStop(bar, position, price, signalName); } }
public PositionEventArgs(Execution.Position position) { this.Position = position; }
void checkThrowNewTakeProfitOffsetMakesSense(Position position, double newTakeProfitPositiveOffset) { string msg = this.ReasonWhyNewTakeProfitOffsetDoesntMakeSense(position, newTakeProfitPositiveOffset); if (String.IsNullOrEmpty(msg) == false) throw new Exception(msg); }
public void StopLossNewNegativeOffsetUpdateActivate(Position position, double newStopLossNegativeOffset) { string msig = " StopLossNewNegativeOffsetUpdateActivate(position[" + position + "], newStopLossNegativeOffset[" + newStopLossNegativeOffset + "])"; PositionPrototype proto = position.Prototype; if (proto == null) { string msg = "StopLossNewNegativeOffsetUpdateActivate() can't update StopLoss for a position.Prototype=null: position=[" + position + "]"; throw new Exception(msg); } this.checkThrowNewStopLossOffsetMakesSense(position, newStopLossNegativeOffset); double newActivationOffset = proto.CalcActivationOffsetForNewClosing(newStopLossNegativeOffset); switch (proto.StopLossAlertForAnnihilation.MarketLimitStop) { case MarketLimitStop.StopLimit: #region StopLimit are considered NYI in Backtester.QuoteGenerator; switched to Stops since they do SL job perfectly; //proto.checkOffsetsThrowBeforeAbsorbing(proto.TakeProfitPositiveOffset, newStopLossNegativeOffset, newActivationOffset); if (executor.Backtester.IsBacktestingNow) { // NOPE!!! I WANT ALL ALERTS TO STAY IN HISTORY!!! just move SL in Alert, change Prices immediately; no orderKill/newOrder for StopLoss (Alerts don't have OrdersFollowed) // PositionPrototypeActivator.checkThrowNewPriceMakesSense() made sure Alert!=null // SL_WILL_BE_KILLED proto.StopLossAlertForAnnihilation.PriceScript = proto.OffsetToPrice(newStopLossNegativeOffset); // SL_WILL_BE_KILLED proto.StopLossAlertForAnnihilation.PriceStopLimitActivation = proto.OffsetToPrice(newActivationOffset); proto.SetNewStopLossOffsets(newStopLossNegativeOffset, newActivationOffset); // TODO: don't forget about backtesting and MarketSim (implement OppMover for offline) executor.MarketSimStreaming.SimulateStopLossMoved(proto.StopLossAlertForAnnihilation); } else { executor.DataSource.BrokerProvider.MoveStopLossOrderProcessorInvoker(proto, newActivationOffset, newStopLossNegativeOffset); } break; #endregion case MarketLimitStop.Stop: if (executor.Backtester.IsBacktestingNow) { proto.SetNewStopLossOffsets(newStopLossNegativeOffset, 0); // TODO: don't forget about backtesting and MarketSim (implement OppMover for offline) executor.MarketSimStreaming.SimulateStopLossMoved(proto.StopLossAlertForAnnihilation); } else { executor.DataSource.BrokerProvider.MoveStopLossOrderProcessorInvoker(proto, 0, newStopLossNegativeOffset); } break; default: string msg = "UNSUPPORTED_STOP_LOSS_CANT_MOVE [" + proto.StopLossAlertForAnnihilation.MarketLimitStop + "] must be Stop or StopLimit(weak support now, almost NYI)"; throw new Exception(msg + msig); } }
public Alert SellAtMarket(Bar bar, Position position, string signalName = "SOLD_AT_MARKET") { return this.Executor.SellOrCoverAlertCreateRegister(bar, position, 0, signalName, Direction.Sell, MarketLimitStop.Market); }