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