Exemple #1
0
        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);
        }
Exemple #2
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);
        }
Exemple #3
0
        public Alert EntryAlertCreate(Bar entryBar, double stopOrLimitPrice, string entrySignalName,
                                      Direction direction, MarketLimitStop entryMarketLimitStop)
        {
            this.checkThrowEntryBarIsValid(entryBar);

            double          priceScriptOrStreaming = stopOrLimitPrice;
            OrderSpreadSide orderSpreadSide        = OrderSpreadSide.Unknown;

            if (entryMarketLimitStop == MarketLimitStop.Market)
            {
                priceScriptOrStreaming = this.getStreamingPriceForMarketOrder(entryMarketLimitStop, direction, out orderSpreadSide);
            }

            PositionLongShort longShortFromDirection = MarketConverter.LongShortFromDirection(direction);
            // ALREADY_ALIGNED_AFTER GetAlignedBidOrAskForTidalOrCrossMarketFromStreaming
            double entryPriceScript = entryBar.ParentBars.SymbolInfo.RoundAlertPriceToPriceLevel(
                priceScriptOrStreaming, true, longShortFromDirection, entryMarketLimitStop);

            double shares = this.executor.PositionSizeCalculate(entryBar, entryPriceScript);

            Alert alert = new Alert(entryBar, shares, entryPriceScript, entrySignalName,
                                    direction, entryMarketLimitStop, orderSpreadSide,
                                    //this.executor.Script,
                                    this.executor.Strategy);

            alert.AbsorbFromExecutor(executor);

            return(alert);
        }
Exemple #4
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);
        }
Exemple #5
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);
        }
Exemple #6
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);
        }
        public Market GetMarketInformation(long marketId)
        {
            GetMarketInformationRequest request = new GetMarketInformationRequest();

            request.MarketIds = new long[] { marketId };


            GetMarketInformationResponse response = _proxy.GetMarketInformation(request);

            if (response.ReturnStatus.Code != 0)
            {
                throw new Exception(response.ReturnStatus.Description);
            }


            // Since only receive one marketId as param then can assume will always be just one market returned.
            Market[] marketToReturn = MarketConverter.ConvertMarketTypeCollection(response.Markets);
            return(marketToReturn[0]);
        }
        public Market GetPrices(long marketId)
        {
            GetPricesRequest request = new GetPricesRequest();

            request.MarketIds = new long[] { marketId };
            request.NumberAgainstPricesRequired = 3;
            request.NumberForPricesRequired     = 3;


            GetPricesResponse response = _proxy.GetPrices(request);

            if (response.ReturnStatus.Code != 0)
            {
                throw new Exception(response.ReturnStatus.Description);
            }


            // Since only receive one marketId as param then can assume will always be just one market returned.
            Market[] marketToReturn = MarketConverter.ConvertMarketTypeWithPricesCollection(response.MarketPrices);
            return(marketToReturn[0]);
        }
Exemple #9
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;
        }
Exemple #10
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);
        }