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 string ReasonWhyPlacingProtoDoesntMakeSense(PositionPrototype proto, bool internalCallee = false) { double lastPrice = executor.DataSource.StreamingProvider.StreamingDataSnapshot.LastQuoteGetPriceForMarketOrder(proto.Symbol); Quote quote = executor.DataSource.StreamingProvider.StreamingDataSnapshot.LastQuoteGetForSymbol(proto.Symbol); double priceBestBidAsk = executor.DataSource.StreamingProvider.StreamingDataSnapshot.BidOrAskFor(proto.Symbol, proto.LongShort); bool willBeExecutedImmediately = false; MarketLimitStop planningEntryUsing = MarketConverter.EntryMarketLimitStopFromDirection( executor.Bars.BarStreamingCloneReadonly.Close, proto.PriceEntry, proto.LongShort); string msg = ""; Direction dir = MarketConverter.EntryDirectionFromLongShort(proto.LongShort); switch (dir) { case Direction.Buy: if (proto.PriceEntry > priceBestBidAsk) { willBeExecutedImmediately = true; msg = "proto.PriceEntry[" + proto.PriceEntry + "] > Bid[" + priceBestBidAsk + "]" + " your Alert.EntryPrice goes above current price" + " so the planningEntryUsing[" + planningEntryUsing + "] will be activated/filled immediately..." + " //proto[" + proto + "]"; } break; case Direction.Short: if (proto.PriceEntry < priceBestBidAsk) { willBeExecutedImmediately = true; msg = "proto.PriceEntry[" + proto.PriceEntry + "] < Ask[" + priceBestBidAsk + "]" + " your Alert.EntryPrice goes below current price" + " so the planningEntryUsing[" + planningEntryUsing + "] will be activated/filled immediately..." + " //proto[" + proto + "]"; } break; default: msg = "I refuse to PlaceOnce(proto) for.Direction=[" + dir + "] - must be Buy or Sell only!!!"; break; } if (internalCallee == true) { msg += " (Script is strongly recommented to check proto.EntryPrice first so we don't pass unexpected position entries to the Market)"; } return(msg); }
public void PlaceOnce(PositionPrototype proto) { if (proto.PriceEntry == 0) { string msg = "market orders can't be found in OrdersPending"; } if (this.checkPrototypeAlreadyPlaced(proto)) { return; } //this.checkThrowPlacingProtoMakesSense(proto); proto.checkTPOffsetThrowBeforeAbsorbing(proto.TakeProfitPositiveOffset); proto.checkSLOffsetsThrowBeforeAbsorbing(proto.StopLossNegativeOffset, proto.StopLossActivationNegativeOffset); //bool a = this.executor.BacktesterFacade.IsBacktestingNow; Position posWithAlert = executor.BuyOrShortAlertCreateRegister( executor.Bars.BarStreaming, proto.PriceEntry, "protoEntry@" + proto.PriceEntry, MarketConverter.EntryDirectionFromLongShort(proto.LongShort), MarketConverter.EntryMarketLimitStopFromDirection( executor.Bars.BarStreamingCloneReadonly.Close, proto.PriceEntry, proto.LongShort) ); if (posWithAlert == null) { string msg = "man I don't understand this null; out-of-bar limit should still leave a pending Alert.PositionAffected"; throw new Exception(msg); } if (posWithAlert.Prototype != null) { 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); } posWithAlert.Prototype = proto; }
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); }