예제 #1
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);
        }
예제 #2
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);
        }
예제 #3
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;
        }
예제 #4
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);
        }