コード例 #1
0
		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;
		}
コード例 #2
0
        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);
            }
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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));
            //}
        }
コード例 #5
0
        private void placePrototypeOncePositionClosed(Bar bar)
        {
            bool isBacktesting = this.Executor.Backtester.IsBacktestingNow;

            //WHATS_THE_DIFFERENCE? if (isBacktesting) return;

            if (bar.ParentBarsIndex == 138)
            {
                //Debugger.Break();
            }

            if (base.HasPositionsOpenNow)
            {
                return;
            }

            if (base.HasAlertsPending)
            {
                // only kill pending entries, but leave activated SL & TP for an open position UNTOUCHED !!!!
                ExecutionDataSnapshot snap     = this.Executor.ExecutionDataSnapshot;
                List <Alert>          pendings = snap.AlertsPendingSafeCopy;
                if (pendings.Count > 0)
                {
                    string msg = pendings.Count + " last AlertsPending[" + snap.AlertsPending[pendings.Count - 1] + "]";
                    //PrintDebug(msg);
                    foreach (Alert alert in pendings)
                    {
                        int wasntFilledDuringPastNbars = bar.ParentBarsIndex - alert.PlacedBarIndex;
                        if (wasntFilledDuringPastNbars >= 30)
                        {
                            //if (alert.PositionAffected.Prototype != null) {}
                            //base.Executor.CallbackAlertKilledInvokeScript(alert);
                            base.AlertKillPending(alert);
                        }
                    }
                }
                return;
            }

            double protoPlacementOffsetPct = 1;
            double TPpct  = 2;
            double SLpct  = -1;
            double SLApct = -0.8;

            double protoPlacement = bar.Close + bar.Close * protoPlacementOffsetPct / 100;
            double TP             = bar.Close * TPpct / 100;
            double SL             = bar.Close * SLpct / 100;
            double SLactivation   = bar.Close * SLApct / 100;

            SLactivation = 0;                   // when SLactivation == 0 Prototype generates Stop alert instead of StopLoss

            PositionPrototype protoLong  = new PositionPrototype(this.Bars.Symbol, PositionLongShort.Long, protoPlacement, TP, SL, SLactivation);
            PositionPrototype protoShort = new PositionPrototype(this.Bars.Symbol, PositionLongShort.Short, -protoPlacement, TP, SL, SLactivation);
            //PositionPrototype protoFixed = new PositionPrototype(this.Bars.Symbol, PositionLongShort.Long, 158000, +150.0, -50.0, -40.0);

            //PositionPrototype proto = barNewStaticArrived.Close < 158000 ? protoLong : protoShort;
            PositionPrototype proto = protoLong;

            base.Executor.PositionPrototypeActivator.PlaceOnce(proto);
        }
コード例 #6
0
		private bool checkPrototypeAlreadyPlaced(PositionPrototype proto) {
			foreach (Alert alert in executor.ExecutionDataSnapshot.AlertsPending) {
				Position pos = alert.PositionAffected;
				if (pos == null) continue;
				if (pos.Prototype == null) continue;
				if (pos.Prototype.IsIdenticalTo(proto)) return true;
			}
			return false;
		}
コード例 #7
0
        void checkThrowPlacingProtoMakesSense(PositionPrototype proto)
        {
            string msg = this.ReasonWhyPlacingProtoDoesntMakeSense(proto);

            if (String.IsNullOrEmpty(msg) == false)
            {
                throw new Exception(msg);
            }
        }
コード例 #8
0
        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);
        }
コード例 #9
0
        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);
            }
        }
コード例 #10
0
        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);
        }
コード例 #11
0
		private void placePrototypeOncePositionClosed(Bar bar) {
			bool isBacktesting = this.Executor.Backtester.IsBacktestingNow;
			//WHATS_THE_DIFFERENCE? if (isBacktesting) return;

			if (bar.ParentBarsIndex == 138) {
				//Debugger.Break();
			}

			if (base.HasPositionsOpenNow) return;

			if (base.HasAlertsPending) {
				// only kill pending entries, but leave activated SL & TP for an open position UNTOUCHED !!!!
				ExecutionDataSnapshot snap = this.Executor.ExecutionDataSnapshot;
				List<Alert> pendings = snap.AlertsPendingSafeCopy;
				if (pendings.Count > 0) {
					string msg = pendings.Count + " last AlertsPending[" + snap.AlertsPending[pendings.Count - 1] + "]";
					//PrintDebug(msg);
					foreach (Alert alert in pendings) {
						int wasntFilledDuringPastNbars = bar.ParentBarsIndex - alert.PlacedBarIndex;
						if (wasntFilledDuringPastNbars >= 30) {
							//if (alert.PositionAffected.Prototype != null) {}
							//base.Executor.CallbackAlertKilledInvokeScript(alert);
							base.AlertKillPending(alert);
						}
					}
				}
				return;
			}

			double protoPlacementOffsetPct = 1;
			double TPpct = 2;
			double SLpct = -1;
			double SLApct = -0.8;

			double protoPlacement = bar.Close + bar.Close * protoPlacementOffsetPct / 100;
			double TP = bar.Close * TPpct / 100;
			double SL = bar.Close * SLpct / 100;
			double SLactivation = bar.Close * SLApct / 100;
			SLactivation = 0;	// when SLactivation == 0 Prototype generates Stop alert instead of StopLoss

			PositionPrototype protoLong = new PositionPrototype(this.Bars.Symbol, PositionLongShort.Long, protoPlacement, TP, SL, SLactivation);
			PositionPrototype protoShort = new PositionPrototype(this.Bars.Symbol, PositionLongShort.Short, -protoPlacement, TP, SL, SLactivation);
			//PositionPrototype protoFixed = new PositionPrototype(this.Bars.Symbol, PositionLongShort.Long, 158000, +150.0, -50.0, -40.0);

			//PositionPrototype proto = barNewStaticArrived.Close < 158000 ? protoLong : protoShort;
			PositionPrototype proto = protoLong;
			base.Executor.PositionPrototypeActivator.PlaceOnce(proto);
		}
コード例 #12
0
        public List <Alert> PositionPrototypeKillWhateverIsPending(PositionPrototype proto, string signalName)
        {
            List <Alert> alertsSubmittedToKill = new List <Alert>();

            if (proto.StopLossAlertForAnnihilation != null)
            {
                this.AlertKillPending(proto.StopLossAlertForAnnihilation);
                alertsSubmittedToKill.Add(proto.StopLossAlertForAnnihilation);
            }
            if (proto.TakeProfitAlertForAnnihilation != null)
            {
                this.AlertKillPending(proto.TakeProfitAlertForAnnihilation);
                alertsSubmittedToKill.Add(proto.TakeProfitAlertForAnnihilation);
            }
            return(alertsSubmittedToKill);
        }
コード例 #13
0
        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);
        }
コード例 #14
0
 private bool checkPrototypeAlreadyPlaced(PositionPrototype proto)
 {
     foreach (Alert alert in executor.ExecutionDataSnapshot.AlertsPending)
     {
         Position pos = alert.PositionAffected;
         if (pos == null)
         {
             continue;
         }
         if (pos.Prototype == null)
         {
             continue;
         }
         if (pos.Prototype.IsIdenticalTo(proto))
         {
             return(true);
         }
     }
     return(false);
 }
コード例 #15
0
        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;
        }
コード例 #16
0
 public void MoveTakeProfitOrderProcessorInvoker(PositionPrototype proto, double newTakeProfitPositiveOffset)
 {
     // broker providers might put some additional order processing,
     // but they must call OrderProcessor.MoveStopLoss() or imitate similar mechanism
     this.OrderProcessor.MoveTakeProfit(proto, newTakeProfitPositiveOffset);
 }
コード例 #17
0
		public void MoveTakeProfitOrderProcessorInvoker(PositionPrototype proto, double newTakeProfitPositiveOffset) {
			// broker providers might put some additional order processing,
			// but they must call OrderProcessor.MoveStopLoss() or imitate similar mechanism
			this.OrderProcessor.MoveTakeProfit(proto, newTakeProfitPositiveOffset);
		}
コード例 #18
0
		public virtual void MoveStopLossOrderProcessorInvoker(PositionPrototype proto, double newActivationOffset, double newStopLossNegativeOffset) {
			// broker providers might put some additional order processing,
			// but they must call OrderProcessor.MoveStopLoss() or imitate similar mechanism
			this.OrderProcessor.MoveStopLoss(proto, newActivationOffset, newStopLossNegativeOffset);
		}
コード例 #19
0
		public void MoveTakeProfit(PositionPrototype proto, double newTakeProfitPositiveOffset) {
			if (proto.TakeProfitAlertForAnnihilation == null) {
				string msg = "I refuse to move TakeProfit order because proto.TakeProfitAlertForAnnihilation=null";
				throw new Exception(msg);
			}
			if (proto.TakeProfitAlertForAnnihilation.OrderFollowed == null) {
				string msg = "I refuse to move TakeProfit order because proto.TakeProfitAlertForAnnihilation.OrderFollowed=null";
				throw new Exception(msg);
			}

			Order order2killAndReplace = proto.TakeProfitAlertForAnnihilation.OrderFollowed;

			OrderState stateBeforeActiveAssummingSubmitting = order2killAndReplace.State;
			OrderState stateBeforeKilledAssumingActive = OrderState.Unknown;

			string msig = "MoveTakeProfit(" + proto.TakeProfitPositiveOffset + "=>" + newTakeProfitPositiveOffset + "): ";

			// 1. hook onKilled=>submitNew
			OrderPostProcessorStateHook takeProfitGotKilledHook = new OrderPostProcessorStateHook("TakeProfitGotKilledHook",
				order2killAndReplace, OrderState.Killed,
				delegate(Order takeProfitKilled, ReporterPokeUnit pokeUnit) {
					string msg = msig + "takeProfitGotKilledHook(): invoking OnTakeProfitKilledCreateNewTakeProfitAndAddToPokeUnit() "
						+ " [" + stateBeforeKilledAssumingActive + "] => "
						+ "[" + takeProfitKilled.State + "]";
					takeProfitKilled.AppendMessage(msg);
					this.OnTakeProfitKilledCreateNewTakeProfitAndAddToPokeUnit(takeProfitKilled, newTakeProfitPositiveOffset, pokeUnit);
				}
			);

			// 2. hook onActive=>kill
			OrderPostProcessorStateHook takeProfitReceivedActiveCallback = new OrderPostProcessorStateHook("TakeProfitReceivedActiveCallback",
				order2killAndReplace, OrderState.Active,
				delegate(Order takeProfitToBeKilled, ReporterPokeUnit pokeUnit) {
					string msg = msig + "takeProfitReceivedActiveCallback(): invoking KillOrderUsingKillerOrder() "
						+ " [" + stateBeforeActiveAssummingSubmitting + "] => "
						+ "[" + takeProfitToBeKilled.State + "]";
					takeProfitToBeKilled.AppendMessage(msg);
					stateBeforeKilledAssumingActive = takeProfitToBeKilled.State;
					this.KillOrderUsingKillerOrder(order2killAndReplace);
				}
			);

			this.OPPstatusCallbacks.AddStateChangedHook(takeProfitReceivedActiveCallback);
			this.OPPstatusCallbacks.AddStateChangedHook(takeProfitGotKilledHook);

			this.AppendOrderMessageAndPropagateCheckThrowOrderNull(proto.TakeProfitAlertForAnnihilation.OrderFollowed, msig + ": hooked takeProfitReceivedActiveCallback() and takeProfitGotKilledHook()");
		}
コード例 #20
0
        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);
        }
コード例 #21
0
		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;
		}
コード例 #22
0
		void checkThrowPlacingProtoMakesSense(PositionPrototype proto) {
			string msg = this.ReasonWhyPlacingProtoDoesntMakeSense(proto);
			if (String.IsNullOrEmpty(msg) == false) throw new Exception(msg);
		}
コード例 #23
0
		public List<Alert> PositionPrototypeKillWhateverIsPending(PositionPrototype proto, string signalName) {
			List<Alert> alertsSubmittedToKill = new List<Alert>();
			if (proto.StopLossAlertForAnnihilation != null) {
				this.AlertKillPending(proto.StopLossAlertForAnnihilation);
				alertsSubmittedToKill.Add(proto.StopLossAlertForAnnihilation);
			}
			if (proto.TakeProfitAlertForAnnihilation != null) {
				this.AlertKillPending(proto.TakeProfitAlertForAnnihilation);
				alertsSubmittedToKill.Add(proto.TakeProfitAlertForAnnihilation);
			}
			return alertsSubmittedToKill;
		}
コード例 #24
0
 public virtual void MoveStopLossOrderProcessorInvoker(PositionPrototype proto, double newActivationOffset, double newStopLossNegativeOffset)
 {
     // broker providers might put some additional order processing,
     // but they must call OrderProcessor.MoveStopLoss() or imitate similar mechanism
     this.OrderProcessor.MoveStopLoss(proto, newActivationOffset, newStopLossNegativeOffset);
 }