Ejemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="side"></param>
        /// <param name="retracement"></param>
        /// <returns></returns>
        protected virtual Tuple <double, double, double> GetOrderPrices(double spread, string side, Thrust thrust)
        {
            double entryPrice, stopLossPrice;

            FibonacciRetracement retracement = (FibonacciRetracement)thrust.Study;

            if (side == MACC.Constants.SignalSide.Buy)
            {
                entryPrice    = retracement.LevelPrice(FibonacciLevel.R382) + (0.75 * spread);
                stopLossPrice = retracement.LevelPrice(FibonacciLevel.R618) - (0.75 * spread);

                if (thrust.FillZoneReached() && thrust.TakeProfitZoneReached())
                {
                    stopLossPrice = retracement.LevelPrice(FibonacciLevel.R500) - (0.75 * spread);
                }
            }
            else
            {
                entryPrice    = retracement.LevelPrice(FibonacciLevel.R382) - (0.75 * spread);
                stopLossPrice = retracement.LevelPrice(FibonacciLevel.R618) + (0.75 * spread);

                if (thrust.FillZoneReached() && thrust.TakeProfitZoneReached())
                {
                    stopLossPrice = retracement.LevelPrice(FibonacciLevel.R500) + (0.75 * spread);
                }
            }

            int    multiplier      = side == MACC.Constants.SignalSide.Buy ? 1 : -1;
            double r382Price       = retracement.LevelPrice(FibonacciLevel.R382);
            double takeProfitPrice = r382Price + (0.618 * Math.Abs(retracement.FocusPrice - r382Price) * multiplier);

            var orderPrices = Tuple.Create <double, double, double>(entryPrice, stopLossPrice, takeProfitPrice);

            return(orderPrices);
        }
Ejemplo n.º 2
0
        public void GetFibboLevels_GivenBearishTrend_ShouldReturnExtensionLevelLessThanPointAandB(double pointA, double pointB)
        {
            //Arrange
            //Act
            var fibboLevels = FibonacciRetracement.GetFibboLevels(pointA, pointB);

            //Assert
            Assert.Less(fibboLevels.Extension1_Level_161_8, pointB);
            Assert.Less(fibboLevels.Extension2_Level_261_8, pointB);
            Assert.Less(fibboLevels.Extension3_Level_423_6, pointB);
            Assert.Less(fibboLevels.Extension4_Level_685_4, pointB);
            Assert.Less(fibboLevels.Extension5_Level_1109, pointB);
            Assert.Less(fibboLevels.Extension6_Level_1794_4, pointB);
            Assert.Less(fibboLevels.Extension7_Level_2903_4, pointB);
            Assert.Less(fibboLevels.Extension8_Level_4697_8, pointB);
            Assert.Less(fibboLevels.Extension9_Level_7601_2, pointB);
            Assert.Less(fibboLevels.Extension10_Level_12299, pointB);

            Assert.Less(fibboLevels.Extension1_Level_161_8, pointA);
            Assert.Less(fibboLevels.Extension2_Level_261_8, pointA);
            Assert.Less(fibboLevels.Extension3_Level_423_6, pointA);
            Assert.Less(fibboLevels.Extension4_Level_685_4, pointA);
            Assert.Less(fibboLevels.Extension5_Level_1109, pointA);
            Assert.Less(fibboLevels.Extension6_Level_1794_4, pointA);
            Assert.Less(fibboLevels.Extension7_Level_2903_4, pointA);
            Assert.Less(fibboLevels.Extension8_Level_4697_8, pointA);
            Assert.Less(fibboLevels.Extension9_Level_7601_2, pointA);
            Assert.Less(fibboLevels.Extension10_Level_12299, pointA);
        }
Ejemplo n.º 3
0
        public void GetFibboLevels_GivenBearishTrend_ShouldReturnExtensionLevelsInDescendingOrder(double pointA, double pointB)
        {
            //Arrange
            //Act
            var fibboLevels = FibonacciRetracement.GetFibboLevels(pointA, pointB);

            //Assert
            Assert.Less(fibboLevels.Extension10_Level_12299, fibboLevels.Extension9_Level_7601_2);
            Assert.Less(fibboLevels.Extension9_Level_7601_2, fibboLevels.Extension8_Level_4697_8);
            Assert.Less(fibboLevels.Extension8_Level_4697_8, fibboLevels.Extension7_Level_2903_4);
            Assert.Less(fibboLevels.Extension7_Level_2903_4, fibboLevels.Extension6_Level_1794_4);
            Assert.Less(fibboLevels.Extension6_Level_1794_4, fibboLevels.Extension5_Level_1109);
            Assert.Less(fibboLevels.Extension5_Level_1109, fibboLevels.Extension4_Level_685_4);
            Assert.Less(fibboLevels.Extension4_Level_685_4, fibboLevels.Extension3_Level_423_6);
            Assert.Less(fibboLevels.Extension3_Level_423_6, fibboLevels.Extension2_Level_261_8);
            Assert.Less(fibboLevels.Extension2_Level_261_8, fibboLevels.Extension1_Level_161_8);
            Assert.Less(fibboLevels.Extension1_Level_161_8, pointB);

            Assert.AreEqual(fibboLevels.PointB, pointB);

            Assert.Less(fibboLevels.RetracementLevel_61_8, fibboLevels.RetracementLevel_38_2);
            Assert.Less(fibboLevels.RetracementLevel_38_2, fibboLevels.RetracementLevel_23_6);
            Assert.Less(fibboLevels.RetracementLevel_23_6, pointA);
            Assert.AreEqual(fibboLevels.PointA, pointA);
        }
Ejemplo n.º 4
0
        public void GetFibboLevels_Given50Level_ShouldReturnLevelsWithCorrectValue(double pointA, double pointB)
        {
            //Arrange
            var level50Prie = (pointA + pointB) / 2;
            //Act
            var fibboLevelGivenLevel = FibonacciRetracement.GetFibboLevels(pointA, pointB, 0.5);

            //Assert

            Assert.AreEqual(level50Prie, fibboLevelGivenLevel);
        }
Ejemplo n.º 5
0
        public void GetFibboLevels_GivenLevelAndBullishTrend_ShouldReturnLevelsWithCorrectValues(double pointA, double pointB, double level)
        {
            //Arrange
            //Act
            var fibboLevels          = FibonacciRetracement.GetFibboLevels(pointA, pointB);
            var fibboLevelGivenLevel = FibonacciRetracement.GetFibboLevels(pointA, pointB, level);

            //Assert
            switch (level)
            {
            case Fibonacci.Extension1_Level_161_8:
                Assert.AreEqual(fibboLevels.Extension1_Level_161_8, fibboLevelGivenLevel);
                break;

            case Fibonacci.Extension2_Level_261_8:
                Assert.AreEqual(fibboLevels.Extension2_Level_261_8, fibboLevelGivenLevel);
                break;

            case Fibonacci.Extension3_Level_423_6:
                Assert.AreEqual(fibboLevels.Extension3_Level_423_6, fibboLevelGivenLevel);
                break;

            case Fibonacci.Extension4_Level_685_4:
                Assert.AreEqual(fibboLevels.Extension4_Level_685_4, fibboLevelGivenLevel);
                break;

            case Fibonacci.Extension5_Level_1109:
                Assert.AreEqual(fibboLevels.Extension5_Level_1109, fibboLevelGivenLevel);
                break;

            case Fibonacci.Extension6_Level_1794_4:
                Assert.AreEqual(fibboLevels.Extension6_Level_1794_4, fibboLevelGivenLevel);
                break;

            case Fibonacci.Extension7_Level_2903_4:
                Assert.AreEqual(fibboLevels.Extension7_Level_2903_4, fibboLevelGivenLevel);
                break;

            case Fibonacci.Extension8_Level_4697_8:
                Assert.AreEqual(fibboLevels.Extension8_Level_4697_8, fibboLevelGivenLevel);
                break;

            case Fibonacci.Extension9_Level_7601_2:
                Assert.AreEqual(fibboLevels.Extension9_Level_7601_2, fibboLevelGivenLevel);
                break;

            case Fibonacci.Extension10_Level_12299:
                Assert.AreEqual(fibboLevels.Extension10_Level_12299, fibboLevelGivenLevel);
                break;
            }
        }
Ejemplo n.º 6
0
        protected void CreateOrUpdateFibRetracement()
        {
            FibonacciRetracement retracement = this.Study as FibonacciRetracement;

            if (retracement == null)
            {
                this.Study = new FibonacciRetracement()
                {
                    AnchorPrice = SignalPrice, AnchorTime = SignalTime
                };
                retracement = this.Study as FibonacciRetracement;
            }

            retracement.FocusPrice = FocusPrice;
            retracement.FocusTime  = FocusTime;
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Sets the extrema price of the thrust Fibonacci retracement
        /// </summary>
        /// <param name="chart">The chart object that contains the retracement.</param>
        /// <param name="side">The direction of the entry signal associated with the retracement.</param>
        /// <param name="focusIndex">The chart index of the retracement focus bar.</param>
        /// <returns></returns>
        protected virtual Thrust SetThrustRetracementExtrema(Chart chart, Thrust thrust)
        {
            int focusIndex = GetFocusIndex(chart, thrust);

            FibonacciRetracement retracement = thrust.Study as FibonacciRetracement;

            double?extremaPrice = null;

            // only if the chart has post-focus frames
            int i = focusIndex + 1;

            if (i < chart.Frames.Count)
            {
                // initialize
                if (thrust.Side == MACC.Constants.SignalSide.Buy)
                {
                    extremaPrice = chart.Frames[focusIndex].Bar.highMid;
                }
                else
                {
                    extremaPrice = chart.Frames[focusIndex].Bar.lowMid;
                }

                // discover
                for (; i < chart.Frames.Count; i++)
                {
                    if (thrust.Side == MACC.Constants.SignalSide.Buy)
                    {
                        extremaPrice = Math.Min(extremaPrice.Value, chart.Frames[i].Bar.lowMid);
                    }
                    else
                    {
                        extremaPrice = Math.Max(extremaPrice.Value, chart.Frames[i].Bar.highMid);
                    }
                }
            }

            retracement.ExtremaPrice = extremaPrice;
            if (retracement.ExtremaChanged())
            {
                retracement.ExtremaIndex = i;
            }

            return(thrust);
        }
Ejemplo n.º 8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="chart"></param>
        /// <param name="side"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public virtual double?GetAdjustedStopLossPrice(Chart chart, IParameters parameters, IDictionary <string, object> state)
        {
            string side;
            Thrust thrust;
            bool   hasProfit;

            #region state validation
            string stateItem = "";
            try
            {
                stateItem = "side";
                side      = (string)state[stateItem];
                stateItem = "thrust";
                thrust    = (Thrust)state[stateItem];
                stateItem = "hasProfit";
                hasProfit = Convert.ToBoolean(state[stateItem]);
            }
            catch (Exception ex)
            {
                throw new ArgumentException(string.Format("State argument is missing or invalid: {0}.", stateItem), ex);
            }
            #endregion

            #region logic
            // if a buy ...
            //    move the stop to the lower of the .500 fib price or [patern lowBid price set by the post-fill price action]
            // if a sell ...
            //    move the stop to the higher of the .500 fib price or [patern highBid price set by the post-fill price action]
            #endregion

            FibonacciRetracement retracement = (FibonacciRetracement)thrust.Study;

            if (!retracement.ExtremaPrice.HasValue)
            {
                return(null);
            }

            double?stopLossPrice = null;
            double r500Price     = retracement.LevelPrice(FibonacciLevel.R500);
            double lastPrice     = chart.Frames.Last().Bar.closeMid;

            double extrema500Delta        = 0;
            double extremaPrice           = retracement.ExtremaPrice.Value;
            double extremaTakeProfitDelta = Math.Abs(thrust.TakeProfitPrice.Value - extremaPrice);
            double takeProfitZoneReachedExtremaCoefficient = parameters.GetDouble("takeProfitZoneReachedExtremaCoefficient") ?? 0.5;

            if (side == MACC.Constants.SignalSide.Buy)
            {
                extrema500Delta = extremaPrice - r500Price;

                if (hasProfit)
                {
                    if (thrust.TakeProfitZoneReached())
                    {
                        stopLossPrice = extremaPrice + (takeProfitZoneReachedExtremaCoefficient * extremaTakeProfitDelta);
                    }
                    else if (extrema500Delta >= 0 && !thrust.ProfitWindowClosed)
                    {
                        stopLossPrice = null;
                    }
                    else if (extrema500Delta >= 0 && thrust.ProfitWindowClosed) // set to extrema or 500?
                    {
                        stopLossPrice = r500Price;
                    }
                    else if (extrema500Delta < 0 && !thrust.ProfitWindowClosed)
                    {
                        stopLossPrice = extremaPrice;
                    }
                    else // extrema500Delta < 0 && profitWindowClosed .. set to r500
                    {
                        stopLossPrice = r500Price;
                    }
                }
                else
                {
                    if (thrust.TakeProfitZoneReached())
                    {
                        stopLossPrice = -1;
                    }
                    if (thrust.ProfitWindowClosed && lastPrice > r500Price)
                    {
                        stopLossPrice = r500Price;
                    }
                    else if (thrust.ProfitWindowClosed && lastPrice <= r500Price)
                    {
                        stopLossPrice = -1; // kill trade
                    }
                    else
                    {
                        stopLossPrice = null;
                    }
                }

                if (stopLossPrice.HasValue)
                {
                    // stopLoss should never move down
                    if (stopLossPrice <= thrust.StopLossPrice)
                    {
                        stopLossPrice = null;
                    }
                    else
                    {
                        stopLossPrice -= chart.HistoricBidAskSpread;
                    }
                }
            }
            else
            {
                extrema500Delta = r500Price - extremaPrice;

                if (hasProfit)
                {
                    if (thrust.TakeProfitZoneReached())
                    {
                        stopLossPrice = extremaPrice - (takeProfitZoneReachedExtremaCoefficient * extremaTakeProfitDelta);
                    }
                    else if (extrema500Delta >= 0 && !thrust.ProfitWindowClosed)
                    {
                        stopLossPrice = null;
                    }
                    else if (extrema500Delta >= 0 && thrust.ProfitWindowClosed)
                    {
                        stopLossPrice = extremaPrice;
                    }
                    else if (extrema500Delta < 0 && !thrust.ProfitWindowClosed)
                    {
                        stopLossPrice = extremaPrice;
                    }
                    else // extrema500Delta < 0 && profitWindowClosed
                    {
                        stopLossPrice = r500Price;
                    }
                }
                else
                {
                    if (thrust.TakeProfitZoneReached())
                    {
                        stopLossPrice = -1;
                    }
                    else if (lastPrice < r500Price && thrust.ProfitWindowClosed)
                    {
                        stopLossPrice = r500Price;
                    }
                    else if (lastPrice >= r500Price && thrust.ProfitWindowClosed)
                    {
                        stopLossPrice = -1; // kill trade .. if not already stopped out
                    }
                    else
                    {
                        stopLossPrice = null;
                    }
                }

                if (stopLossPrice.HasValue)
                {
                    // stopLoss should never move up
                    if (stopLossPrice >= thrust.StopLossPrice)
                    {
                        stopLossPrice = null;
                    }
                    else
                    {
                        stopLossPrice += chart.HistoricBidAskSpread;
                    }
                }
            }

            if (stopLossPrice.HasValue)
            {
                stopLossPrice = Math.Round(stopLossPrice.Value, retracement.LevelPlaces());
            }

            return(stopLossPrice);
        }
Ejemplo n.º 9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="chart"></param>
        /// <param name="retracement"></param>
        /// <param name="side"></param>
        /// <returns></returns>
        protected virtual double?GetAdjustedTakeProfitPrice(Chart chart, string side, FibonacciRetracement retracement)
        {
            #region logic
            // if a buy ...
            //    move the profit target to 1 or 2 pips under .618 * (thrust.FocusPrice - [pattern lowMid price set by the post-fill price action])
            // if a sell ...
            //    move the profit target to 1 or 2 pips above .618 * ([pattern lowMid price set by the post-fill price action] - thrust.FocusPrice)
            #endregion

            if (_takeProfitPriceCalculator == null)
            {
                _takeProfitPriceCalculator = ObjectBase.Container.GetExportedValue <ITakeProfitPriceCalculator>("ThrustTakeProfitPriceCalculator");
            }

            Dictionary <string, object> state = new Dictionary <string, object>();
            state.Add("side", side);
            state.Add("retracement", retracement);

            return(_takeProfitPriceCalculator.GetAdjustedTakeProfitPrice(chart, Parameters, state));
        }
Ejemplo n.º 10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="chart"></param>
        /// <param name="thrust"></param>
        /// <param name="retracement"></param>
        protected virtual async void ManageOrder(Chart chart, Thrust thrust)
        {
            StrategyTransaction[] transactions = null;
            StrategyTransaction   orderTransaction, fillTransaction, cancelTransaction, exitTransaction;

            // get transaction collection from db
            int orderTransactionID = thrust.StrategyTransactionID.GetValueOrDefault();

            transactions = await StrategyCaller.Instance().GetStrategyTransactionsCollectionAsync(orderTransactionID);

            orderTransaction  = transactions.FirstOrDefault(t => t.StrategyTransactionID == orderTransactionID);
            fillTransaction   = transactions.FirstOrDefault(t => t.BrokerOrderID != null && t.Type == MACC.Constants.TransactionTypes.OrderFilled);
            cancelTransaction = transactions.FirstOrDefault(t => t.BrokerOrderID != null && t.Type == MACC.Constants.TransactionTypes.OrderCancel);
            exitTransaction   = transactions.FirstOrDefault(t => t.BrokerTradeID != null && t.Type != MACC.Constants.TransactionTypes.TradeUpdate);

            bool purgeInActiveThrust = true;

            if (fillTransaction == null)
            {
                if (cancelTransaction != null)
                {
                    // order cancelled

                    thrust.Active = false;
                }
                else
                {
                    // order open

                    if (!thrust.Active)
                    {
                        // cancel the order
                        // the cancel transaction will be written to the db by the event stream handler
                        await Rest.DeleteOrderAsync(_accountId, Convert.ToInt64(orderTransaction.BrokerTransactionID));
                    }
                    else
                    {
                        if (thrust.FocusChanged() || (thrust.FillZoneReached() && thrust.TakeProfitZoneReached()))
                        {
                            AddAlgorithmMessage(string.Format("UPDATE ORDER: {0}: FCH-{1}: FZR-{2}: TPR-{3}", orderTransaction.Instrument, thrust.FocusChanged(), thrust.FillZoneReached(), thrust.TakeProfitZoneReached()));
                            UpdateEntryOrder(orderTransaction, chart, thrust);
                        }
                    }
                }
            }
            else
            {
                if (exitTransaction == null)
                {
                    // order filled

                    purgeInActiveThrust = false;
                    FibonacciRetracement retracement = (FibonacciRetracement)thrust.Study;

                    #region get open trade info
                    long  tradeId   = Convert.ToInt64(fillTransaction.BrokerTransactionID);
                    Frame fillFrame = chart.Frames.LastOrDefault(f => Convert.ToDateTime(f.Bar.time).ToUniversalTime() <= fillTransaction.Time);
                    int   fillIndex = chart.Frames.IndexOf(fillFrame);
                    #endregion

                    #region get takeProfitPrice and stopLossPrice
                    int profitWaitPeriods = Parameters.GetInteger("thrustProfitWaitPeriods") ?? 6;
                    thrust.ProfitWindowClosed = (fillIndex + profitWaitPeriods) < chart.Frames.Count;

                    IPriceBar lastBar   = chart.Frames.Last().Bar;
                    bool      hasProfit = orderTransaction.Side == MACC.Constants.SignalSide.Buy ? lastBar.closeMid > fillTransaction.Price : lastBar.closeMid < fillTransaction.Price;

                    #region stopLossPrice & takeProfitPrice logic
                    // adjust stopLossPrice and takeProfitPrice
                    // if a buy ...
                    //    move the stop to the lower of the .500 fib price or [patern lowMid price set by the post-fill price action]
                    //    move the profit target to 1 or 2 pips under .618 * (thrust.FocusPrice - [pattern lowMid price set by the post-fill price action])
                    // if a sell ...
                    //    move the stop to the higher of the .500 fib price or [patern highMid price set by the post-fill price action]
                    //    move the profit target to 1 or 2 pips above .618 * ([pattern lowMid price set by the post-fill price action] - thrust.FocusPrice)
                    #endregion

                    double?takeProfitPrice = GetAdjustedTakeProfitPrice(chart, thrust.Side, retracement);
                    AddAlgorithmMessage(string.Format("GET SLP: {0}: TPZ-{1}: PWC-{2}: XTP-{3}: CLP-{4}: PFT-{5}", fillTransaction.Instrument, thrust.TakeProfitZoneReached(), thrust.ProfitWindowClosed, retracement.ExtremaPrice, lastBar.closeMid, hasProfit));
                    double?stopLossPrice = GetAdjustedStopLossPrice(chart, thrust.Side, thrust, hasProfit);
                    #endregion

                    #region kill or update the trade
                    // not profitable && beyond r500 .. kill it
                    if (stopLossPrice.GetValueOrDefault() == -1)
                    {
                        thrust.Active       = false;
                        purgeInActiveThrust = true;

                        try
                        {
                            await Rest.DeleteTradeAsync(_accountId, tradeId);
                        }
                        catch (Exception e)
                        {
                            AddAlgorithmMessage(string.Format("CLOSE TRADE {0} Failed: {1}", tradeId, e.Message), true, TraceEventType.Error);
                        }
                    }
                    else
                    {
                        if ((takeProfitPrice ?? thrust.TakeProfitPrice) != thrust.TakeProfitPrice || (stopLossPrice ?? thrust.StopLossPrice) != thrust.StopLossPrice)
                        {
                            AddAlgorithmMessage(string.Format("UPDATE TRADE: {0}: TPZ-{1}: PWC-{2}: XTP-{3}: CLP-{4}: TP-{5}: TTP-{6}: SL-{7}: TSL-{8}", fillTransaction.Instrument, thrust.TakeProfitZoneReached(), thrust.ProfitWindowClosed, retracement.ExtremaPrice, lastBar.closeMid, takeProfitPrice, thrust.TakeProfitPrice, stopLossPrice, thrust.StopLossPrice));
                            UpdateOpenTrade(thrust, tradeId, takeProfitPrice, stopLossPrice, retracement.LevelPlaces());
                        }
                    }
                    #endregion
                }
                else
                {
                    // trade closed

                    #region about closed trades
                    // if coll includes a stopLossFilled or takeProfitFilled ..
                    // set thrust.Active = false
                    // this be done server side when the strategyTransaction from the stream is saved
                    // the signal should be found on the server and signal.Active should be set to false
                    // do it here also
                    #endregion

                    thrust.Active = false;
                }
            }

            if (!thrust.Active && purgeInActiveThrust)
            {
                await PurgeThrust(chart, thrust);
            }
        }
Ejemplo n.º 11
0
        protected Thrust SetThrustActive(Chart chart, Thrust thrust, bool isNewThrust)
        {
            thrust.Active = true;

            List <Frame> afterFocusFrames = chart.Frames.Skip(GetFocusIndex(chart, thrust) + 1).ToList();

            if (isNewThrust)
            {
                // should an order be placed?

                // thrust range must be >= _percentRange
                //    should some consideration of the time frame happen?
                //    .006 is for hourly
                //    use a lower value for lower time frame scalping?
                if (Math.Abs(thrust.FocusPrice - thrust.SignalPrice) / thrust.SignalPrice < _minThrustPercentRange)
                {
                    thrust.Active = false;
                    return(thrust);
                }

                if (thrust.ReactionToFocusSpan < _minReactionToFocusSpan)
                {
                    thrust.Active = false;
                    return(thrust);
                }

                if (afterFocusFrames.Count() == 0)
                {
                    return(thrust);
                }
                else
                {
                    FibonacciRetracement retracement = thrust.Study as FibonacciRetracement;

                    Frame r382ReachedOrExceededFrame = afterFocusFrames.FirstOrDefault(frame =>
                    {
                        if (thrust.Direction == EPatternDirection.Up)
                        {
                            if (frame.Bar.lowMid <= retracement.LevelPrice(FibonacciLevel.R382))
                            {
                                return(true);
                            }
                        }
                        else
                        {
                            if (frame.Bar.highMid >= retracement.LevelPrice(FibonacciLevel.R382))
                            {
                                return(true);
                            }
                        }

                        return(false);
                    });

                    thrust.Active = r382ReachedOrExceededFrame == null;
                    return(thrust);
                }
            }
            else
            {
                // should the order be cancelled if not yet filled?
                // if filled, a 'false' from this doesn't matter
                #region afterFocusAcross3x3Count function
                Func <EPatternDirection, short> afterFocusAcross3x3Count = (direction) =>
                {
                    short across3x3Count          = 0;
                    Frame firstConfirmedAcross3x3 = null;

                    foreach (Frame frame in afterFocusFrames)
                    {
                        IIndicator displaced3x3 = frame.Indicators.First(k => k.Type == IndicatorType.DisplacedMovingAverage && k.ParentOrdinal == 0);

                        if (direction == EPatternDirection.Up)
                        {
                            // grab the first bar below the 3x3 on close
                            if (frame.Bar.closeMid < displaced3x3.Value && firstConfirmedAcross3x3 == null)
                            {
                                firstConfirmedAcross3x3 = frame;
                                continue;
                            }

                            if (firstConfirmedAcross3x3 != null && frame.Bar.lowMid < displaced3x3.Value)
                            {
                                across3x3Count++;
                            }
                        }
                        else
                        {
                            // grab the first bar above the 3x3 on close
                            if (frame.Bar.closeMid > displaced3x3.Value && firstConfirmedAcross3x3 == null)
                            {
                                firstConfirmedAcross3x3 = frame;
                                continue;
                            }

                            if (firstConfirmedAcross3x3 != null && frame.Bar.highMid > displaced3x3.Value)
                            {
                                across3x3Count++;
                            }
                        }
                    }

                    return(across3x3Count);
                };
                #endregion

                // enforce a reactionToFocusSpan of 9 bars to filter out 'turn' thrusts
                //    turn thrusts happen detection triggers on bars at turns in price
                //    these are new thrusts but need 'seasoning' (ie. >= 9 bars) to be trade worthy
                // enforce Dinapoli rule on no more than 3 bars across 3x3 after initial closing bar across 3x3
                thrust.Active = afterFocusAcross3x3Count(thrust.Direction) <= _maxAfterFocusAcross3x3Count;
                return(thrust);
            }
        }
Ejemplo n.º 12
0
        protected virtual Thrust SetThrustTakeProfitZoneReached(Chart chart, Thrust thrust)
        {
            FibonacciRetracement retracement = thrust.Study as FibonacciRetracement;

            #region did price reach the takeProfit zone?
            if (thrust.FillZoneReached())
            {
                double?      searchTakeProfitPrice = null;
                List <Frame> searchFrames          = null;

                if (!thrust.TakeProfitZoneReached())
                {
                    searchTakeProfitPrice = thrust.TakeProfitPrice.Value;
                    searchFrames          = chart.Frames.Skip(thrust.FillZoneReachedIndex.Value + 1).ToList();
                }
                else
                {
                    if (retracement.ExtremaChanged())
                    {
                        int    multiplier = thrust.Side == MACC.Constants.SignalSide.Buy ? 1 : -1;
                        double r382Price  = retracement.LevelPrice(FibonacciLevel.R382);
                        searchTakeProfitPrice = r382Price + (0.618 * Math.Abs(retracement.FocusPrice - r382Price) * multiplier);

                        searchFrames = chart.Frames.Skip(retracement.ExtremaIndex.Value + 1).ToList();
                    }
                }

                Frame takeProfitZoneReachedFrame = searchFrames.FirstOrDefault(frame =>
                {
                    double extremaToTakeProfitZoneDelta = _takeProfitZoneReachedCoefficient * Math.Abs(searchTakeProfitPrice.Value - retracement.ExtremaPrice.Value);

                    bool takeProfitZoneReached = false;

                    if (thrust.Direction == EPatternDirection.Up)
                    {
                        takeProfitZoneReached = (frame.Bar.highMid >= retracement.ExtremaPrice.Value + extremaToTakeProfitZoneDelta);
                    }
                    else
                    {
                        takeProfitZoneReached = (frame.Bar.lowMid <= retracement.ExtremaPrice.Value - extremaToTakeProfitZoneDelta);
                    }

                    if (takeProfitZoneReached)
                    {
                        thrust.TakeProfitZoneReachedIndex      = chart.Frames.IndexOf(frame);
                        thrust.TakeProfitZoneReachedFocusPrice = thrust.FocusPrice;
                        return(true);
                    }

                    return(false);
                });
            }
            #endregion

            // is it a breakout?
            if (thrust.TakeProfitZoneReached())
            {
                double breakoutDelta = thrust.SignalPrice * _focusBreakoutCoefficient * _minThrustPercentRange;

                if (thrust.Direction == EPatternDirection.Up)
                {
                    thrust.Breakout = thrust.FocusPrice >= thrust.TakeProfitZoneReachedFocusPrice.Value + breakoutDelta;
                }
                else
                {
                    thrust.Breakout = thrust.FocusPrice <= thrust.TakeProfitZoneReachedFocusPrice.Value - breakoutDelta;
                }

                if (thrust.Breakout)
                {
                    thrust.FillZoneReachedIndex            = null;
                    thrust.TakeProfitZoneReachedIndex      = null;
                    thrust.TakeProfitZoneReachedFocusPrice = null;
                }
            }

            return(thrust);
        }