コード例 #1
0
        /// <summary>
        ///     Intrabar Scanning
        /// </summary>
        private static bool IntrabarScanning(int bar, BacktestEval eval, ref double current,
                                             ref int reachedIntrabar, ref int tradedIntrabar,
                                             bool isTopReachable, bool isBottomReachable,
                                             bool isHigherPrice, bool isLowerPrice,
                                             double priceHigher, double priceLower,
                                             Order orderHigher, Order orderLower,
                                             bool isClosingAmbiguity)
        {
            double high = High[bar];
            double low = Low[bar];
            double close = Close[bar];
            bool isScanningResult = false;

            if (eval == BacktestEval.None)
            {
                // There is no more orders
                if (!session[bar].IsTopReached && !session[bar].IsBottomReached)
                {
                    // Neither the top nor the bottom was reached
                    bool goUpward = false;
                    for (int intraBar = reachedIntrabar; intraBar < IntraBarBars[bar]; intraBar++)
                    {
                        reachedIntrabar = intraBar;

                        if (IntraBarData[bar][intraBar].High + sigma > high)
                        {
                            // Top found
                            goUpward = true;
                            isScanningResult = true;
                        }

                        if (IntraBarData[bar][intraBar].Low - sigma < low)
                        {
                            // Bottom found
                            if (isScanningResult)
                            {
                                // Top and Bottom into the same intrabar
                                isScanningResult = false;
                                break;
                            }
                            isScanningResult = true;
                        }

                        if (isScanningResult)
                            break;
                    }

                    if (isScanningResult)
                    {
                        if (goUpward)
                        {
                            // Hit the Top
                            current = high;
                            session[bar].SetWayPoint(high, WayPointType.High);
                            session[bar].IsTopReached = true;
                        }
                        else
                        {
                            // Hit the Bottom
                            current = low;
                            session[bar].SetWayPoint(low, WayPointType.Low);
                            session[bar].IsBottomReached = true;
                        }
                    }
                }
                else if (!session[bar].IsTopReached)
                {
                    // Whether hit the Top
                    for (int intraBar = reachedIntrabar; intraBar < IntraBarBars[bar]; intraBar++)
                    {
                        reachedIntrabar = intraBar;

                        if (IntraBarData[bar][intraBar].High + sigma > high)
                        {
                            // Top found
                            current = high;
                            session[bar].SetWayPoint(high, WayPointType.High);
                            session[bar].IsTopReached = true;
                            isScanningResult = true;
                            break;
                        }
                    }
                }
                else if (!session[bar].IsBottomReached)
                {
                    // Whether hit the Bottom
                    for (int intraBar = reachedIntrabar; intraBar < IntraBarBars[bar]; intraBar++)
                    {
                        reachedIntrabar = intraBar;

                        if (IntraBarData[bar][intraBar].Low - sigma < low)
                        {
                            // Bottom found
                            current = low;
                            session[bar].SetWayPoint(low, WayPointType.Low);
                            session[bar].IsBottomReached = true;
                            isScanningResult = true;
                            break;
                        }
                    }
                }
            }

            if (eval == BacktestEval.Correct)
            {
                // Hit the order or the top / bottom
                Order theOrder = null;
                double thePrice = 0;
                if (isHigherPrice)
                {
                    theOrder = orderHigher;
                    thePrice = priceHigher;
                }
                else if (isLowerPrice)
                {
                    theOrder = orderLower;
                    thePrice = priceLower;
                }

                if (!session[bar].IsBottomReached && isBottomReachable)
                {
                    // The order or the bottom
                    bool goUpward = false;
                    for (int intraBar = reachedIntrabar; intraBar < IntraBarBars[bar]; intraBar++)
                    {
                        reachedIntrabar = intraBar;

                        if (IntraBarData[bar][intraBar].High + sigma > thePrice)
                        {
                            // The order is reached
                            goUpward = true;
                            isScanningResult = true;
                        }

                        if (IntraBarData[bar][intraBar].Low - sigma < low)
                        {
                            // Bottom is reached
                            if (isScanningResult)
                            {
                                // The Order and Bottom into the same intrabar
                                isScanningResult = false;
                                break;
                            }
                            isScanningResult = true;
                        }

                        if (isScanningResult)
                            break;
                    }

                    if (isScanningResult)
                    {
                        if (goUpward)
                        {
                            // Execute
                            if (tradedIntrabar == reachedIntrabar)
                            {
                                return false;
                            }
                            current = thePrice;
                            ExecOrd(bar, theOrder, thePrice, eval);
                            tradedIntrabar = reachedIntrabar;
                        }
                        else
                        {
                            // Hit the Bottom
                            current = low;
                            session[bar].SetWayPoint(low, WayPointType.Low);
                            session[bar].IsBottomReached = true;
                        }
                    }
                }
                else if (!session[bar].IsTopReached && isTopReachable)
                {
                    // The order or the Top
                    bool goUpward = false;
                    for (int intraBar = reachedIntrabar; intraBar < IntraBarBars[bar]; intraBar++)
                    {
                        reachedIntrabar = intraBar;

                        if (IntraBarData[bar][intraBar].High + sigma > high)
                        {
                            // The Top is reached
                            goUpward = true;
                            isScanningResult = true;
                        }

                        if (IntraBarData[bar][intraBar].Low - sigma < thePrice)
                        {
                            // The order is reached
                            if (isScanningResult)
                            {
                                // The Top and the order are into the same intrabar
                                isScanningResult = false;
                                break;
                            }

                            // The order is reachable downwards
                            isScanningResult = true;
                        }

                        if (isScanningResult)
                            break;
                    }

                    if (isScanningResult)
                    {
                        if (goUpward)
                        {
                            // Hit the Top
                            current = high;
                            session[bar].SetWayPoint(high, WayPointType.High);
                            session[bar].IsTopReached = true;
                        }
                        else
                        {
                            // Execute
                            if (tradedIntrabar == reachedIntrabar)
                            {
                                return false;
                            }
                            current = thePrice;
                            ExecOrd(bar, theOrder, thePrice, eval);
                            tradedIntrabar = reachedIntrabar;
                        }
                    }
                }
                else
                {
                    // Execute the order
                    for (int intraBar = reachedIntrabar; intraBar < IntraBarBars[bar]; intraBar++)
                    {
                        reachedIntrabar = intraBar;

                        if (IntraBarData[bar][intraBar].High + sigma > thePrice &&
                            IntraBarData[bar][intraBar].Low - sigma < thePrice)
                        {
                            // Order reached
                            if (tradedIntrabar == reachedIntrabar)
                            {
                                return false;
                            }
                            current = thePrice;
                            ExecOrd(bar, theOrder, thePrice, eval);
                            isScanningResult = true;
                            tradedIntrabar = reachedIntrabar;
                            break;
                        }
                    }
                }
            }
            else if (eval == BacktestEval.Ambiguous)
            {
                // Ambiguous - two orders or order and bar closing
                if (!isClosingAmbiguity)
                {
                    // Execute the the first reached order
                    bool executeUpper = false;
                    for (int intraBar = reachedIntrabar; intraBar < IntraBarBars[bar]; intraBar++)
                    {
                        reachedIntrabar = intraBar;

                        if (IntraBarData[bar][intraBar].High + sigma > priceHigher)
                        {
                            // Upper order is reached
                            executeUpper = true;
                            isScanningResult = true;
                        }

                        if (IntraBarData[bar][intraBar].Low - sigma < priceLower)
                        {
                            // Lower order is reached
                            if (isScanningResult)
                            {
                                // Top and Bottom into the same intrabar
                                isScanningResult = false;
                                break;
                            }
                            isScanningResult = true;
                        }

                        if (isScanningResult)
                            break;
                    }

                    if (isScanningResult)
                    {
                        Order theOrder;
                        double thePrice;
                        if (executeUpper)
                        {
                            theOrder = orderHigher;
                            thePrice = priceHigher;
                        }
                        else
                        {
                            theOrder = orderLower;
                            thePrice = priceLower;
                        }

                        if (tradedIntrabar == reachedIntrabar)
                        {
                            return false;
                        }
                        eval = BacktestEval.Correct;
                        current = thePrice;
                        ExecOrd(bar, theOrder, thePrice, eval);
                        tradedIntrabar = reachedIntrabar;
                    }
                }
                else
                {
                    // Execute or exit the bar
                    var theOrder = new Order();
                    double thePrice = 0;
                    if (isHigherPrice)
                    {
                        theOrder = orderHigher;
                        thePrice = priceHigher;
                    }
                    else if (isLowerPrice)
                    {
                        theOrder = orderLower;
                        thePrice = priceLower;
                    }

                    bool executeOrder = false;
                    if (isHigherPrice)
                    {
                        for (int intraBar = reachedIntrabar; intraBar < IntraBarBars[bar]; intraBar++)
                        {
                            reachedIntrabar = intraBar;

                            if (IntraBarData[bar][intraBar].High + sigma > thePrice)
                            {
                                // The order is reached
                                executeOrder = true;
                                break;
                            }
                        }
                    }
                    else if (isLowerPrice)
                    {
                        // The priceLower or Exit the bar
                        for (int b = reachedIntrabar; b < IntraBarBars[bar]; b++)
                        {
                            reachedIntrabar = b;

                            if (IntraBarData[bar][b].Low - sigma < thePrice)
                            {
                                // The order is reached
                                executeOrder = true;
                                break;
                            }
                        }
                    }

                    if (executeOrder)
                    {
                        // Execute the order
                        if (tradedIntrabar == reachedIntrabar)
                        {
                            return false;
                        }
                        current = thePrice;
                        eval = BacktestEval.Correct;
                        ExecOrd(bar, theOrder, thePrice, eval);
                        tradedIntrabar = reachedIntrabar;
                    }
                    else
                    {
                        // Exit the bar
                        current = close;
                        theOrder.OrdStatus = OrderStatus.Cancelled;
                        session[bar].BacktestEval = BacktestEval.Correct;
                    }
                    isScanningResult = true;
                }
            }

            return isScanningResult;
        }
コード例 #2
0
        /// <summary>
        ///     Random Execution Method
        /// </summary>
        private static void RandomMethod(int bar, BacktestEval eval, ref double current,
                                         bool isTopReachable, bool isBottomReachable,
                                         bool isHigherPrice, bool isLowerPrice,
                                         double priceHigher, double priceLower,
                                         Order orderHigher, Order orderLower,
                                         bool isClosingAmbiguity)
        {
            double high = High[bar];
            double low = Low[bar];
            double close = Close[bar];
            var random = new Random();

            if (eval == BacktestEval.None)
            {
                // There is no more orders
                if (!session[bar].IsTopReached && !session[bar].IsBottomReached)
                {
                    // Neither the top nor the bottom was reached
                    var upRange = (int) Math.Round((high - current)/InstrProperties.Point);
                    var downRange = (int) Math.Round((current - low)/InstrProperties.Point);
                    upRange = upRange < 0 ? 0 : upRange;
                    downRange = downRange < 0 ? 0 : downRange;
                    if (downRange + downRange == 0)
                    {
                        upRange = 1;
                        downRange = 1;
                    }
                    int rand = random.Next(upRange + downRange);
                    bool isHitHigh;

                    if (upRange > downRange)
                        isHitHigh = rand > upRange;
                    else
                        isHitHigh = rand < downRange;

                    if (isHitHigh)
                    {
                        // Hit the Top
                        current = high;
                        session[bar].SetWayPoint(high, WayPointType.High);
                        session[bar].IsTopReached = true;
                    }
                    else
                    {
                        // Hit the Bottom
                        current = low;
                        session[bar].SetWayPoint(low, WayPointType.Low);
                        session[bar].IsBottomReached = true;
                    }
                }
                else if (!session[bar].IsTopReached)
                {
                    // Hit the Top
                    current = high;
                    session[bar].SetWayPoint(high, WayPointType.High);
                    session[bar].IsTopReached = true;
                }
                else if (!session[bar].IsBottomReached)
                {
                    // Hit the Bottom
                    current = low;
                    session[bar].SetWayPoint(low, WayPointType.Low);
                    session[bar].IsBottomReached = true;
                }
            }
            if (eval == BacktestEval.Correct)
            {
                // Hit the order or the top/bottom
                Order theOrder = null;
                double thePrice = 0;
                if (isHigherPrice)
                {
                    theOrder = orderHigher;
                    thePrice = priceHigher;
                }
                else if (isLowerPrice)
                {
                    theOrder = orderLower;
                    thePrice = priceLower;
                }

                if (!session[bar].IsBottomReached && isBottomReachable)
                {
                    // The order or the bottom
                    var iUpRange = (int) Math.Round((thePrice - current)/InstrProperties.Point);
                    var iDnRange = (int) Math.Round((current - low)/InstrProperties.Point);
                    iUpRange = iUpRange < 0 ? 0 : iUpRange;
                    iDnRange = iDnRange < 0 ? 0 : iDnRange;
                    if (iDnRange + iDnRange == 0)
                    {
                        iUpRange = 1;
                        iDnRange = 1;
                    }
                    int rand = random.Next(iUpRange + iDnRange);
                    bool executeUpper;

                    if (iUpRange > iDnRange)
                        executeUpper = rand > iUpRange;
                    else
                        executeUpper = rand < iDnRange;

                    if (executeUpper)
                    {
                        // Execute
                        current = thePrice;
                        ExecOrd(bar, theOrder, thePrice, eval);
                    }
                    else
                    {
                        // Hit the Bottom
                        current = low;
                        session[bar].SetWayPoint(low, WayPointType.Low);
                        session[bar].IsBottomReached = true;
                    }
                }
                else if (!session[bar].IsTopReached && isTopReachable)
                {
                    // The order or the Top
                    var upRange = (int) Math.Round((high - current)/InstrProperties.Point);
                    var downRange = (int) Math.Round((current - thePrice)/InstrProperties.Point);
                    upRange = upRange < 0 ? 0 : upRange;
                    downRange = downRange < 0 ? 0 : downRange;
                    if (downRange + downRange == 0)
                    {
                        upRange = 1;
                        downRange = 1;
                    }
                    int rand = random.Next(upRange + downRange);
                    bool executeUpper;

                    if (upRange > downRange)
                        executeUpper = rand > upRange;
                    else
                        executeUpper = rand < downRange;

                    if (executeUpper)
                    {
                        // Hit the Top
                        current = high;
                        session[bar].SetWayPoint(high, WayPointType.High);
                        session[bar].IsTopReached = true;
                    }
                    else
                    {
                        // Execute
                        current = thePrice;
                        ExecOrd(bar, theOrder, thePrice, eval);
                    }
                }
                else
                {
                    // Execute the order
                    current = thePrice;
                    ExecOrd(bar, theOrder, thePrice, eval);
                }
            }
            else if (eval == BacktestEval.Ambiguous)
            {
                // Ambiguous - two orders or order and bar closing
                if (!isClosingAmbiguity)
                {
                    // Execute the randomly chosen order
                    var upRange = (int) Math.Round((priceHigher - current)/InstrProperties.Point);
                    var downRange = (int) Math.Round((current - priceLower)/InstrProperties.Point);
                    upRange = upRange < 0 ? 0 : upRange;
                    downRange = downRange < 0 ? 0 : downRange;
                    if (downRange + downRange == 0)
                    {
                        upRange = 1;
                        downRange = 1;
                    }
                    int rand = random.Next(upRange + downRange);
                    bool executeUpper;

                    if (upRange > downRange)
                        executeUpper = rand > upRange;
                    else
                        executeUpper = rand < downRange;

                    Order theOrder;
                    double thePrice;
                    if (executeUpper)
                    {
                        theOrder = orderHigher;
                        thePrice = priceHigher;
                    }
                    else
                    {
                        theOrder = orderLower;
                        thePrice = priceLower;
                    }
                    current = thePrice;
                    ExecOrd(bar, theOrder, thePrice, eval);
                }
                else
                {
                    // Execute or exit the bar
                    if (isHigherPrice)
                    {
                        var upRange = (int) Math.Round((priceHigher - current)/InstrProperties.Point);
                        var downRange = (int) Math.Round((close - current)/InstrProperties.Point);
                        upRange = upRange < 0 ? 0 : upRange;
                        downRange = downRange < 0 ? 0 : downRange;
                        if (downRange + downRange == 0)
                        {
                            upRange = 1;
                            downRange = 0;
                        }
                        int rand = random.Next(upRange + downRange);

                        if (rand > upRange)
                        {
                            // Execute the order
                            current = priceHigher;
                            ExecOrd(bar, orderHigher, priceHigher, eval);
                        }
                        else
                        {
                            // Exit the bar
                            current = close;
                            orderHigher.OrdStatus = OrderStatus.Cancelled;
                            session[bar].BacktestEval = BacktestEval.Ambiguous;
                        }
                    }
                    else if (isLowerPrice)
                    {
                        // The priceLower or Exit the bar
                        var upRange = (int) Math.Round((current - close)/InstrProperties.Point);
                        var downRange = (int) Math.Round((current - priceLower)/InstrProperties.Point);
                        upRange = upRange < 0 ? 0 : upRange;
                        downRange = downRange < 0 ? 0 : downRange;
                        if (downRange + downRange == 0)
                        {
                            upRange = 0;
                            downRange = 1;
                        }
                        int rand = random.Next(upRange + downRange);

                        if (rand > downRange)
                        {
                            // Execute the order
                            current = priceLower;
                            ExecOrd(bar, orderLower, priceLower, eval);
                        }
                        else
                        {
                            // Exit the bar
                            current = close;
                            orderLower.OrdStatus = OrderStatus.Cancelled;
                            session[bar].BacktestEval = BacktestEval.Ambiguous;
                        }
                    }
                }
            }
        }
コード例 #3
0
        /// <summary>
        ///     Optimistic / Pessimistic Method
        /// </summary>
        private static void OptimisticPessimisticMethod(int bar, BacktestEval eval, ref double current,
                                                        bool isTopReachable, bool isBottomReachable,
                                                        bool isHigherPrice, bool isLowerPrice,
                                                        double priceHigher, double priceLower,
                                                        Order orderHigher, Order orderLower,
                                                        bool isClosingAmbiguity)
        {
            double open = Open[bar];
            double high = High[bar];
            double low = Low[bar];
            double close = Close[bar];

            bool isOptimistic = InterpolationMethod == InterpolationMethod.Optimistic;

            if (eval == BacktestEval.None)
            {
                // There is no more orders
                if (!session[bar].IsTopReached && !session[bar].IsBottomReached)
                {
                    // Neither the top nor the bottom was reached
                    if (close < open)
                    {
                        // Hit the Top
                        current = high;
                        session[bar].SetWayPoint(high, WayPointType.High);
                        session[bar].IsTopReached = true;
                    }
                    else
                    {
                        // Hit the Bottom
                        current = low;
                        session[bar].SetWayPoint(low, WayPointType.Low);
                        session[bar].IsBottomReached = true;
                    }
                }
                else if (!session[bar].IsTopReached)
                {
                    // Hit the Top
                    current = high;
                    session[bar].SetWayPoint(high, WayPointType.High);
                    session[bar].IsTopReached = true;
                }
                else if (!session[bar].IsBottomReached)
                {
                    // Hit the Bottom
                    current = low;
                    session[bar].SetWayPoint(low, WayPointType.Low);
                    session[bar].IsBottomReached = true;
                }
            }
            if (eval == BacktestEval.Correct)
            {
                // Hit the order or the top/bottom
                var theOrder = new Order();
                double thePrice = 0;
                if (isHigherPrice)
                {
                    theOrder = orderHigher;
                    thePrice = priceHigher;
                }
                else if (isLowerPrice)
                {
                    theOrder = orderLower;
                    thePrice = priceLower;
                }

                if (!session[bar].IsBottomReached && isBottomReachable)
                {
                    // The order or the bottom
                    bool goUpward;

                    if (current < low + sigma)
                        goUpward = false;
                    else if (thePrice - current < sigma)
                        goUpward = true;
                    else if (theOrder.OrdDir == OrderDirection.Buy)
                        goUpward = !isOptimistic;
                    else if (theOrder.OrdDir == OrderDirection.Sell)
                        goUpward = isOptimistic;
                    else
                        goUpward = thePrice - current < current - low;

                    if (goUpward)
                    {
                        // Execute order
                        current = thePrice;
                        ExecOrd(bar, theOrder, thePrice, eval);
                    }
                    else
                    {
                        // Hit the Bottom
                        current = low;
                        session[bar].SetWayPoint(low, WayPointType.Low);
                        session[bar].IsBottomReached = true;
                    }
                }
                else if (!session[bar].IsTopReached && isTopReachable)
                {
                    // The order or the top
                    bool goUpward;

                    if (current > high - sigma)
                        goUpward = true;
                    else if (current - thePrice < sigma)
                        goUpward = false;
                    else if (theOrder.OrdDir == OrderDirection.Buy)
                        goUpward = !isOptimistic;
                    else if (theOrder.OrdDir == OrderDirection.Sell)
                        goUpward = isOptimistic;
                    else
                        goUpward = high - current < current - thePrice;

                    if (goUpward)
                    {
                        // Hit the Top
                        current = high;
                        session[bar].SetWayPoint(high, WayPointType.High);
                        session[bar].IsTopReached = true;
                    }
                    else
                    {
                        // Execute order
                        current = thePrice;
                        ExecOrd(bar, theOrder, thePrice, eval);
                    }
                }
                else
                {
                    // Execute the order
                    current = thePrice;
                    ExecOrd(bar, theOrder, thePrice, eval);
                }
            }
            else if (eval == BacktestEval.Ambiguous)
            {
                // Ambiguous - two orders or order and bar closing
                if (!isClosingAmbiguity)
                {
                    // Execute one of both orders
                    bool executeUpper;

                    if (priceHigher - current < sigma)
                        executeUpper = true;
                    else if (current - priceLower < sigma)
                        executeUpper = false;
                    else if (session[bar].Summary.PosDir == PosDirection.Long)
                        executeUpper = isOptimistic;
                    else if (session[bar].Summary.PosDir == PosDirection.Short)
                        executeUpper = !isOptimistic;
                    else
                    {
                        if (orderHigher.OrdDir == OrderDirection.Buy && orderLower.OrdDir == OrderDirection.Buy)
                            executeUpper = !isOptimistic;
                        else if (orderHigher.OrdDir == OrderDirection.Sell && orderLower.OrdDir == OrderDirection.Sell)
                            executeUpper = isOptimistic;
                        else if (orderHigher.OrdDir == OrderDirection.Buy && orderLower.OrdDir == OrderDirection.Sell)
                        {
                            if (current < close)
                                executeUpper = isOptimistic;
                            else
                                executeUpper = !isOptimistic;

                            if (Strategy.OppSignalAction == OppositeDirSignalAction.Reverse)
                                executeUpper = !executeUpper;
                        }
                        else
                        {
                            if (current < close)
                                executeUpper = !isOptimistic;
                            else
                                executeUpper = isOptimistic;

                            if (Strategy.OppSignalAction == OppositeDirSignalAction.Reverse)
                                executeUpper = !executeUpper;
                        }
                    }

                    Order theOrder;
                    double thePrice;
                    if (executeUpper)
                    {
                        theOrder = orderHigher;
                        thePrice = priceHigher;
                    }
                    else
                    {
                        theOrder = orderLower;
                        thePrice = priceLower;
                    }
                    current = thePrice;

                    ExecOrd(bar, theOrder, thePrice, eval);
                }
                else
                {
                    // Execute or exit the bar
                    if (isHigherPrice)
                    {
                        bool toExecute = false;
                        if (session[bar].Summary.PosDir == PosDirection.Long)
                            toExecute = isOptimistic;
                        else if (session[bar].Summary.PosDir == PosDirection.Short)
                            toExecute = !isOptimistic;
                        else if (orderHigher.OrdDir == OrderDirection.Buy)
                            toExecute = !isOptimistic;
                        else if (orderHigher.OrdDir == OrderDirection.Sell)
                            toExecute = isOptimistic;

                        if (toExecute)
                        {
                            // Execute
                            current = priceHigher;
                            ExecOrd(bar, orderHigher, priceHigher, eval);
                        }
                        else
                        {
                            // Exit the bar
                            current = close;
                            orderHigher.OrdStatus = OrderStatus.Cancelled;
                            session[bar].BacktestEval = BacktestEval.Ambiguous;
                        }
                    }
                    else if (isLowerPrice)
                    {
                        // The priceLower or Exit the bar
                        bool toExecute = false;

                        if (session[bar].Summary.PosDir == PosDirection.Long)
                            toExecute = !isOptimistic;
                        else if (session[bar].Summary.PosDir == PosDirection.Short)
                            toExecute = isOptimistic;
                        else if (orderLower.OrdDir == OrderDirection.Buy)
                            toExecute = isOptimistic;
                        else if (orderLower.OrdDir == OrderDirection.Sell)
                            toExecute = !isOptimistic;

                        if (toExecute)
                        {
                            // Execute
                            current = priceLower;
                            ExecOrd(bar, orderLower, priceLower, eval);
                        }
                        else
                        {
                            // Exit the bar
                            current = close;
                            orderLower.OrdStatus = OrderStatus.Cancelled;
                            session[bar].BacktestEval = BacktestEval.Ambiguous;
                        }
                    }
                }
            }
        }
コード例 #4
0
        /// <summary>
        ///     Tick Scanning
        /// </summary>
        private static bool TickScanning(int bar, BacktestEval eval,
                                         ref double current, ref int reachedTick,
                                         bool isTopReachable, bool isBottomReachable,
                                         bool isHigherPrice, bool isLowerPrice,
                                         double priceHigher, double priceLower,
                                         Order orderHigher, Order orderLower,
                                         bool isClosingAmbiguity)
        {
            double high = High[bar];
            double low = Low[bar];
            double close = Close[bar];
            bool isScanningResult = false;

            if (eval == BacktestEval.None)
            {
                // There isn't any orders
                if (!session[bar].IsTopReached && !session[bar].IsBottomReached)
                {
                    // Neither the top nor the bottom was reached
                    int tickCount = TickData[bar].Length;
                    for (int tick = reachedTick; tick < tickCount; tick++)
                    {
                        reachedTick = tick;
                        if (TickData[bar][tick] + sigma > high)
                        {
                            // Top found
                            current = high;
                            session[bar].SetWayPoint(high, WayPointType.High);
                            session[bar].IsTopReached = true;
                            isScanningResult = true;
                            break;
                        }
                        if (TickData[bar][tick] - sigma < low)
                        {
                            // Bottom found
                            current = low;
                            session[bar].SetWayPoint(low, WayPointType.Low);
                            session[bar].IsBottomReached = true;
                            isScanningResult = true;
                            break;
                        }
                    }
                }
                else if (!session[bar].IsTopReached)
                {
                    // Whether hit the Top
                    int tickCount = TickData[bar].Length;
                    for (int tick = reachedTick; tick < tickCount; tick++)
                    {
                        reachedTick = tick;
                        if (TickData[bar][tick] + sigma > high)
                        {
                            // Top found
                            current = high;
                            session[bar].SetWayPoint(high, WayPointType.High);
                            session[bar].IsTopReached = true;
                            isScanningResult = true;
                            break;
                        }
                    }
                }
                else if (!session[bar].IsBottomReached)
                {
                    // Whether hit the Bottom
                    int tickCount = TickData[bar].Length;
                    for (int tick = reachedTick; tick < tickCount; tick++)
                    {
                        reachedTick = tick;
                        if (TickData[bar][tick] - sigma < low)
                        {
                            // Bottom found
                            current = low;
                            session[bar].SetWayPoint(low, WayPointType.Low);
                            session[bar].IsBottomReached = true;
                            isScanningResult = true;
                            break;
                        }
                    }
                }
            }

            if (eval == BacktestEval.Correct)
            {
                // Hit the order or the top / bottom
                Order theOrder = null;
                double thePrice = 0;
                if (isHigherPrice)
                {
                    theOrder = orderHigher;
                    thePrice = priceHigher;
                }
                else if (isLowerPrice)
                {
                    theOrder = orderLower;
                    thePrice = priceLower;
                }

                if (!session[bar].IsBottomReached && isBottomReachable)
                {
                    // The order or the Bottom
                    int tickCount = TickData[bar].Length;
                    for (int tick = reachedTick; tick < tickCount; tick++)
                    {
                        reachedTick = tick;
                        if (TickData[bar][tick] + sigma > thePrice)
                        {
                            // The order is reached
                            current = thePrice;
                            ExecOrd(bar, theOrder, thePrice, BacktestEval.Correct);
                            isScanningResult = true;
                            break;
                        }
                        if (TickData[bar][tick] - sigma < low)
                        {
                            // Bottom is reached
                            current = low;
                            session[bar].SetWayPoint(low, WayPointType.Low);
                            session[bar].IsBottomReached = true;
                            isScanningResult = true;
                            break;
                        }
                    }
                }
                else if (!session[bar].IsTopReached && isTopReachable)
                {
                    // The order or the Top
                    int tickCount = TickData[bar].Length;
                    for (int tick = reachedTick; tick < tickCount; tick++)
                    {
                        reachedTick = tick;
                        if (TickData[bar][tick] + sigma > high)
                        {
                            // The Top is reached
                            current = high;
                            session[bar].SetWayPoint(high, WayPointType.High);
                            session[bar].IsTopReached = true;
                            isScanningResult = true;
                            break;
                        }
                        if (TickData[bar][tick] - sigma < thePrice)
                        {
                            // The order is reached
                            current = thePrice;
                            ExecOrd(bar, theOrder, thePrice, BacktestEval.Correct);
                            isScanningResult = true;
                            break;
                        }
                    }
                }
                else
                {
                    // Execute the order
                    double priceOld = TickData[bar][reachedTick];
                    int tickCount = TickData[bar].Length;
                    for (int tick = reachedTick; tick < tickCount; tick++)
                    {
                        reachedTick = tick;
                        if (priceOld - sigma < thePrice && TickData[bar][tick] + sigma > thePrice ||
                            priceOld + sigma > thePrice && TickData[bar][tick] - sigma < thePrice)
                        {
                            // Order reached
                            current = thePrice;
                            ExecOrd(bar, theOrder, thePrice, BacktestEval.Correct);
                            isScanningResult = true;
                            break;
                        }
                    }
                }
            }
            else if (eval == BacktestEval.Ambiguous)
            {
                // Ambiguous - two orders or order and bar closing
                if (!isClosingAmbiguity)
                {
                    // Execute the the first reached order
                    int tickCount = TickData[bar].Length;
                    for (int tick = reachedTick; tick < tickCount; tick++)
                    {
                        reachedTick = tick;
                        if (TickData[bar][tick] + sigma > priceHigher)
                        {
                            // Upper order is reached
                            current = priceHigher;
                            ExecOrd(bar, orderHigher, priceHigher, BacktestEval.Correct);
                            isScanningResult = true;
                            break;
                        }
                        if (TickData[bar][tick] - sigma < priceLower)
                        {
                            // Lower order is reached
                            current = priceLower;
                            ExecOrd(bar, orderLower, priceLower, BacktestEval.Correct);
                            isScanningResult = true;
                            break;
                        }
                    }
                }
                else
                {
                    // Execute or exit the bar
                    var theOrder = new Order();
                    double thePrice = 0.0;
                    if (isHigherPrice)
                    {
                        theOrder = orderHigher;
                        thePrice = priceHigher;
                    }
                    else if (isLowerPrice)
                    {
                        theOrder = orderLower;
                        thePrice = priceLower;
                    }

                    bool executeOrder = false;
                    if (isHigherPrice)
                    {
                        int tickCount = TickData[bar].Length;
                        for (int tick = reachedTick; tick < tickCount; tick++)
                        {
                            reachedTick = tick;
                            if (TickData[bar][tick] + sigma > thePrice)
                            {
                                // The order is reached
                                executeOrder = true;
                                break;
                            }
                        }
                    }
                    else if (isLowerPrice)
                    {
                        // The priceLower or Exit the bar
                        int tickCount = TickData[bar].Length;
                        for (int tick = reachedTick; tick < tickCount; tick++)
                        {
                            reachedTick = tick;
                            if (TickData[bar][tick] - sigma < thePrice)
                            {
                                // The order is reached
                                executeOrder = true;
                                break;
                            }
                        }
                    }

                    if (executeOrder)
                    {
                        // Execute the order
                        current = thePrice;
                        ExecOrd(bar, theOrder, thePrice, BacktestEval.Correct);
                    }
                    else
                    {
                        // Exit the bar
                        current = close;
                        theOrder.OrdStatus = OrderStatus.Cancelled;
                        session[bar].BacktestEval = BacktestEval.Correct;
                    }

                    isScanningResult = true;
                }
            }

            return isScanningResult;
        }
コード例 #5
0
        /// <summary>
        ///     Shortest route inside the bar Method
        /// </summary>
        private static void ShortestMethod(int bar, BacktestEval eval, ref double current,
                                           bool isTopReachable, bool isBottomReachable,
                                           bool isHigherPrice, bool isLowerPrice,
                                           double priceHigher, double priceLower,
                                           Order orderHigher, Order orderLower,
                                           bool isClosingAmbiguity)
        {
            double open = Open[bar];
            double high = High[bar];
            double low = Low[bar];
            double close = Close[bar];

            bool isGoUpward;
            if (!session[bar].IsTopReached && !session[bar].IsBottomReached)
                isGoUpward = open > close;
            else if (session[bar].IsTopReached && !session[bar].IsBottomReached)
                isGoUpward = false;
            else if (!session[bar].IsTopReached && session[bar].IsBottomReached)
                isGoUpward = true;
            else
                isGoUpward = open > close;

            if (isLowerPrice && current - priceLower < sigma)
                isGoUpward = false;
            if (isHigherPrice && priceHigher - current < sigma)
                isGoUpward = true;

            if (eval == BacktestEval.None)
            {
                // There is no more orders
                if (!session[bar].IsTopReached && !session[bar].IsBottomReached)
                {
                    // Neither the top nor the bottom was reached
                    if (isGoUpward)
                    {
                        // Hit the Top
                        current = high;
                        session[bar].SetWayPoint(high, WayPointType.High);
                        session[bar].IsTopReached = true;
                    }
                    else
                    {
                        // Hit the Bottom
                        current = low;
                        session[bar].SetWayPoint(low, WayPointType.Low);
                        session[bar].IsBottomReached = true;
                    }
                }
                else if (!session[bar].IsTopReached)
                {
                    // Hit the Top
                    current = high;
                    session[bar].SetWayPoint(high, WayPointType.High);
                    session[bar].IsTopReached = true;
                }
                else if (!session[bar].IsBottomReached)
                {
                    // Hit the Bottom
                    current = low;
                    session[bar].SetWayPoint(low, WayPointType.Low);
                    session[bar].IsBottomReached = true;
                }
            }
            if (eval == BacktestEval.Correct)
            {
                // Hit the top/bottom or execute
                Order theOrder = null;
                double thePrice = 0;
                if (isHigherPrice)
                {
                    theOrder = orderHigher;
                    thePrice = priceHigher;
                }
                else if (isLowerPrice)
                {
                    theOrder = orderLower;
                    thePrice = priceLower;
                }

                if (!session[bar].IsBottomReached && isBottomReachable && !isGoUpward)
                {
                    // Hit the Bottom
                    current = low;
                    session[bar].SetWayPoint(low, WayPointType.Low);
                    session[bar].IsBottomReached = true;
                }
                else if (!session[bar].IsTopReached && isTopReachable && isGoUpward)
                {
                    // Hit the Top
                    current = high;
                    session[bar].SetWayPoint(high, WayPointType.High);
                    session[bar].IsTopReached = true;
                }
                else
                {
                    // Execute the order
                    current = thePrice;
                    ExecOrd(bar, theOrder, thePrice, eval);
                }
            }
            else if (eval == BacktestEval.Ambiguous)
            {
                // Ambiguous - two orders or order and bar closing
                if (!isClosingAmbiguity)
                {
                    // Execute the nearest order
                    Order theOrder;
                    double thePrice;

                    if (isGoUpward)
                    {
                        theOrder = orderHigher;
                        thePrice = priceHigher;
                    }
                    else
                    {
                        theOrder = orderLower;
                        thePrice = priceLower;
                    }
                    current = thePrice;
                    ExecOrd(bar, theOrder, thePrice, eval);
                }
                else
                {
                    // Exit the bar
                    current = close;
                    session[bar].BacktestEval = BacktestEval.Ambiguous;
                    if (isHigherPrice)
                        orderHigher.OrdStatus = OrderStatus.Cancelled;
                    else if (isLowerPrice)
                        orderLower.OrdStatus = OrderStatus.Cancelled;
                }
            }
        }
コード例 #6
0
        /// <summary>
        ///     Nearest order first Method
        /// </summary>
        private static void NearestMethod(int bar, BacktestEval eval, ref double current,
                                          bool isTopReachable, bool isBottomReachable,
                                          bool isHigherPrice, bool isLowerPrice,
                                          double priceHigher, double priceLower,
                                          Order orderHigher, Order orderLower,
                                          bool isClosingAmbiguity)
        {
            double open = Open[bar];
            double high = High[bar];
            double low = Low[bar];
            double close = Close[bar];

            if (eval == BacktestEval.None)
            {
                // There is no more orders
                if (!session[bar].IsTopReached && !session[bar].IsBottomReached)
                {
                    // Neither the top nor the bottom was reached
                    if (close < open)
                    {
                        // Hit the Top
                        current = high;
                        session[bar].SetWayPoint(high, WayPointType.High);
                        session[bar].IsTopReached = true;
                    }
                    else
                    {
                        // Hit the Bottom
                        current = low;
                        session[bar].SetWayPoint(low, WayPointType.Low);
                        session[bar].IsBottomReached = true;
                    }
                }
                else if (!session[bar].IsTopReached)
                {
                    // Hit the Top
                    current = high;
                    session[bar].SetWayPoint(high, WayPointType.High);
                    session[bar].IsTopReached = true;
                }
                else if (!session[bar].IsBottomReached)
                {
                    // Hit the Bottom
                    current = low;
                    session[bar].SetWayPoint(low, WayPointType.Low);
                    session[bar].IsBottomReached = true;
                }
            }
            if (eval == BacktestEval.Correct)
            {
                // Hit the order or the top/bottom
                Order theOrder = null;
                double thePrice = 0;
                if (isHigherPrice)
                {
                    theOrder = orderHigher;
                    thePrice = priceHigher;
                }
                else if (isLowerPrice)
                {
                    theOrder = orderLower;
                    thePrice = priceLower;
                }

                if (!session[bar].IsBottomReached && isBottomReachable)
                {
                    // The order or the bottom
                    double upRange = thePrice - current;
                    double downRange = current - low;

                    if (upRange < downRange)
                    {
                        // Execute
                        current = thePrice;
                        ExecOrd(bar, theOrder, thePrice, eval);
                    }
                    else
                    {
                        // Hit the Bottom
                        current = low;
                        session[bar].SetWayPoint(low, WayPointType.Low);
                        session[bar].IsBottomReached = true;
                    }
                }
                else if (!session[bar].IsTopReached && isTopReachable)
                {
                    // The order or the bottom
                    double upRange = high - current;
                    double downRange = current - thePrice;

                    if (upRange < downRange)
                    {
                        // Hit the Top
                        current = high;
                        session[bar].SetWayPoint(high, WayPointType.High);
                        session[bar].IsTopReached = true;
                    }
                    else
                    {
                        // Execute
                        current = thePrice;
                        ExecOrd(bar, theOrder, thePrice, eval);
                    }
                }
                else
                {
                    // Execute the order
                    current = thePrice;
                    ExecOrd(bar, theOrder, thePrice, eval);
                }
            }
            else if (eval == BacktestEval.Ambiguous)
            {
                // Ambiguous - two orders or order and bar closing
                if (!isClosingAmbiguity)
                {
                    // Execute the nearest order
                    double upRange = priceHigher - current;
                    double downRange = current - priceLower;

                    Order theOrder;
                    double thePrice;
                    if (upRange < downRange)
                    {
                        theOrder = orderHigher;
                        thePrice = priceHigher;
                    }
                    else
                    {
                        theOrder = orderLower;
                        thePrice = priceLower;
                    }
                    current = thePrice;
                    ExecOrd(bar, theOrder, thePrice, eval);
                }
                else
                {
                    // Exit the bar
                    double orderRange = isHigherPrice ? priceHigher - current : current - priceLower;
                    double closeRange = Math.Abs(current - close);

                    if (orderRange < closeRange)
                    {
                        // Execute the order
                        Order theOrder;
                        double thePrice;
                        if (isHigherPrice)
                        {
                            theOrder = orderHigher;
                            thePrice = priceHigher;
                        }
                        else
                        {
                            theOrder = orderLower;
                            thePrice = priceLower;
                        }
                        current = thePrice;
                        ExecOrd(bar, theOrder, thePrice, eval);
                    }
                    else
                    {
                        // Cancel the order, go to Close
                        current = close;
                        session[bar].BacktestEval = BacktestEval.Ambiguous;
                        if (isHigherPrice)
                            orderHigher.OrdStatus = OrderStatus.Cancelled;
                        else if (isLowerPrice)
                            orderLower.OrdStatus = OrderStatus.Cancelled;
                    }
                }
            }
        }
コード例 #7
0
        /// <summary>
        ///     Makes a deep copy.
        /// </summary>
        public Order Copy()
        {
            var order = new Order
                {
                    OrdDir = OrdDir,
                    OrdType = OrdType,
                    OrdCond = OrdCond,
                    OrdStatus = OrdStatus,
                    OrdSender = OrdSender,
                    OrdOrigin = OrdOrigin,
                    OrdNumb = OrdNumb,
                    OrdIf = OrdIf,
                    OrdPos = OrdPos,
                    OrdLots = OrdLots,
                    OrdPrice = OrdPrice,
                    OrdPrice2 = OrdPrice2,
                    OrdNote = OrdNote
                };

            return order;
        }
コード例 #8
0
 /// <summary>
 ///     Finds and cancels the exit order of an entry order
 /// </summary>
 private static void FindCancelExitOrder(int bar, Order order)
 {
     for (int ord = 0; ord < session[bar].Orders; ord++)
         if (session[bar].Order[ord].OrdIf == order.OrdNumb)
         {
             session[bar].Order[ord].OrdStatus = OrderStatus.Cancelled;
             break;
         }
 }
コード例 #9
0
        /// <summary>
        ///     Tunes and Executes an order
        /// </summary>
        private static void ExecOrd(int bar, Order order, double price, BacktestEval testEval)
        {
            Position position = session[bar].Summary;
            PosDirection posDir = position.PosDir;
            OrderDirection ordDir = order.OrdDir;
            var wayPointType = WayPointType.None;

            // Orders modification on a fly
            // Checks whether we are on the market
            if (posDir == PosDirection.Long || posDir == PosDirection.Short)
            {
                // We are on the market
                if (order.OrdSender == OrderSender.Open)
                {
                    // Entry orders
                    if (ordDir == OrderDirection.Buy && posDir == PosDirection.Long ||
                        ordDir == OrderDirection.Sell && posDir == PosDirection.Short)
                    {
                        // In case of a Same Dir Signal
                        switch (Strategy.SameSignalAction)
                        {
                            case SameDirSignalAction.Add:
                                order.OrdLots = TradingSize(Strategy.AddingLots, bar);
                                if (position.PosLots + TradingSize(Strategy.AddingLots, bar) <= maximumLots)
                                {
                                    // Adding
                                    wayPointType = WayPointType.Add;
                                }
                                else
                                {
                                    // Cancel the Adding
                                    order.OrdStatus = OrderStatus.Cancelled;
                                    wayPointType = WayPointType.Cancel;
                                    FindCancelExitOrder(bar, order); // Canceling of its exit order
                                }
                                break;
                            case SameDirSignalAction.Winner:
                                order.OrdLots = TradingSize(Strategy.AddingLots, bar);
                                if (position.PosLots + TradingSize(Strategy.AddingLots, bar) <= maximumLots &&
                                    (position.PosDir == PosDirection.Long && position.PosPrice < order.OrdPrice ||
                                     position.PosDir == PosDirection.Short && position.PosPrice > order.OrdPrice))
                                {
                                    // Adding
                                    wayPointType = WayPointType.Add;
                                }
                                else
                                {
                                    // Cancel the Adding
                                    order.OrdStatus = OrderStatus.Cancelled;
                                    wayPointType = WayPointType.Cancel;
                                    FindCancelExitOrder(bar, order); // Canceling of its exit order
                                }
                                break;
                            case SameDirSignalAction.Nothing:
                                order.OrdLots = TradingSize(Strategy.AddingLots, bar);
                                order.OrdStatus = OrderStatus.Cancelled;
                                wayPointType = WayPointType.Cancel;
                                FindCancelExitOrder(bar, order); // Canceling of its exit order
                                break;
                        }
                    }
                    else if (ordDir == OrderDirection.Buy && posDir == PosDirection.Short ||
                             ordDir == OrderDirection.Sell && posDir == PosDirection.Long)
                    {
                        // In case of an Opposite Dir Signal
                        switch (Strategy.OppSignalAction)
                        {
                            case OppositeDirSignalAction.Reduce:
                                if (position.PosLots > TradingSize(Strategy.ReducingLots, bar))
                                {
                                    // Reducing
                                    order.OrdLots = TradingSize(Strategy.ReducingLots, bar);
                                    wayPointType = WayPointType.Reduce;
                                }
                                else
                                {
                                    // Closing
                                    order.OrdLots = position.PosLots;
                                    wayPointType = WayPointType.Exit;
                                }
                                break;
                            case OppositeDirSignalAction.Close:
                                order.OrdLots = position.PosLots;
                                wayPointType = WayPointType.Exit;
                                break;
                            case OppositeDirSignalAction.Reverse:
                                order.OrdLots = position.PosLots + TradingSize(Strategy.EntryLots, bar);
                                wayPointType = WayPointType.Reverse;
                                break;
                            case OppositeDirSignalAction.Nothing:
                                order.OrdStatus = OrderStatus.Cancelled;
                                wayPointType = WayPointType.Cancel;
                                FindCancelExitOrder(bar, order); // Canceling of its exit order
                                break;
                        }
                    }
                }
                else
                {
                    // Exit orders
                    if (ordDir == OrderDirection.Buy && posDir == PosDirection.Short ||
                        ordDir == OrderDirection.Sell && posDir == PosDirection.Long)
                    {
                        // Check for Break Even Activation
                        if (order.OrdOrigin == OrderOrigin.BreakEvenActivation)
                        {
                            // This is a fictive order
                            order.OrdStatus = OrderStatus.Cancelled;
                            wayPointType = WayPointType.Cancel;
                        }
                        else
                        {
                            // The Close orders can only close the position
                            order.OrdLots = position.PosLots;
                            wayPointType = WayPointType.Exit;
                        }
                    }
                    else
                    {
                        // If the direction of the exit order is same as the position's direction
                        // the order have to be cancelled
                        order.OrdStatus = OrderStatus.Cancelled;
                        wayPointType = WayPointType.Cancel;
                    }
                }
            }
            else
            {
                // We are out of the market
                if (order.OrdSender == OrderSender.Open)
                {
                    // Open a new position
                    double entryAmount = TradingSize(Strategy.EntryLots, bar);
                    if (Strategy.UseMartingale && consecutiveLosses > 0)
                    {
                        entryAmount = entryAmount*Math.Pow(Strategy.MartingaleMultiplier, consecutiveLosses);
                        entryAmount = NormalizeEntryLots(entryAmount);
                    }
                    order.OrdLots = Math.Min(entryAmount, maximumLots);
                    wayPointType = WayPointType.Entry;
                }
                else // if (order.OrdSender == OrderSender.Close)
                {
                    // The Close strategy cannot do anything
                    order.OrdStatus = OrderStatus.Cancelled;
                    wayPointType = WayPointType.Cancel;
                }
            }

            // Enter Once can cancel an entry order
            if (hasEnterOnce && order.OrdSender == OrderSender.Open && order.OrdStatus == OrderStatus.Confirmed)
            {
                bool toCancel = false;
                switch (Strategy.Slot[slotEnterOnce].IndParam.ListParam[0].Text)
                {
                    case "Enter no more than once a bar":
                        toCancel = Time[bar] == lastEntryTime;
                        break;
                    case "Enter no more than once a day":
                        toCancel = Time[bar].DayOfYear == lastEntryTime.DayOfYear;
                        break;
                    case "Enter no more than once a week":
                        int lastEntryWeek = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(
                            lastEntryTime, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
                        int currentWeek = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(
                            Time[bar], CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
                        toCancel = lastEntryWeek == currentWeek;
                        break;
                    case "Enter no more than once a month":
                        toCancel = Time[bar].Month == lastEntryTime.Month;
                        break;
                }

                if (toCancel)
                {
                    // Cancel the entry order
                    order.OrdStatus = OrderStatus.Cancelled;
                    wayPointType = WayPointType.Cancel;
                    FindCancelExitOrder(bar, order); // Canceling of its exit order
                }
                else
                    lastEntryTime = Time[bar];
            }

            // Do not trade after Margin Call or after -1000000 Loss
            if (order.OrdSender == OrderSender.Open && order.OrdStatus == OrderStatus.Confirmed)
            {
                if (position.FreeMargin < -1000000 ||
                    Configs.TradeUntilMarginCall && RequiredMargin(order.OrdLots, bar) > position.FreeMargin)
                {
                    // Cancel the entry order
                    order.OrdStatus = OrderStatus.Cancelled;
                    wayPointType = WayPointType.Cancel;
                    FindCancelExitOrder(bar, order); // Canceling of its exit order
                }
            }

            // Executing the order
            if (order.OrdStatus == OrderStatus.Confirmed)
            {
                // Executes the order
                SetPosition(bar, ordDir, order.OrdLots, price, order.OrdNumb);
                order.OrdStatus = OrderStatus.Executed;

                // Set the evaluation
                switch (testEval)
                {
                    case BacktestEval.Error:
                        session[bar].BacktestEval = BacktestEval.Error;
                        break;
                    case BacktestEval.None:
                        break;
                    case BacktestEval.Ambiguous:
                        session[bar].BacktestEval = BacktestEval.Ambiguous;
                        break;
                    case BacktestEval.Unknown:
                        if (session[bar].BacktestEval != BacktestEval.Ambiguous)
                            session[bar].BacktestEval = BacktestEval.Unknown;
                        break;
                    case BacktestEval.Correct:
                        if (session[bar].BacktestEval == BacktestEval.None)
                            session[bar].BacktestEval = BacktestEval.Correct;
                        break;
                }

                // If entry order closes or reverses the position the exit orders of the
                // initial position have to be cancelled
                if (order.OrdSender == OrderSender.Open &&
                    (session[bar].Summary.Transaction == Transaction.Close ||
                     session[bar].Summary.Transaction == Transaction.Reverse))
                {
                    int initialNumber = session[bar].Position[session[bar].Positions - 2].FormOrdNumb;
                    // If the position was opened during the current bar, we can find its exit order
                    bool isFound = false;
                    for (int ord = 0; ord < session[bar].Orders; ord++)
                    {
                        if (session[bar].Order[ord].OrdIf == initialNumber &&
                            session[bar].Order[ord].OrdSender == OrderSender.Close)
                        {
                            session[bar].Order[ord].OrdStatus = OrderStatus.Cancelled;
                            isFound = true;
                            break;
                        }
                    }

                    // In case when the order is not found, this means that the position is transferred
                    // so its exit order is not conditional
                    if (!isFound)
                    {
                        for (int ord = 0; ord < session[bar].Orders; ord++)
                        {
                            if (session[bar].Order[ord].OrdSender == OrderSender.Close &&
                                session[bar].Order[ord].OrdIf == 0)
                            {
                                session[bar].Order[ord].OrdStatus = OrderStatus.Cancelled;
                                break;
                            }
                        }
                    }

                    // Setting the exit order of the current position
                    switch (session[bar].Summary.Transaction)
                    {
                        case Transaction.Close:
                            {
                                // In case of closing we have to cancel the exit order
                                int number = session[bar].Summary.FormOrdNumb;
                                for (int ord = 0; ord < session[bar].Orders; ord++)
                                {
                                    if (session[bar].Order[ord].OrdIf != number) continue;
                                    session[bar].Order[ord].OrdStatus = OrderStatus.Cancelled;
                                    break;
                                }
                            }
                            break;
                        case Transaction.Reduce:
                            {
                                // In case of reducing we have to change the direction of the exit order
                                int number = session[bar].Summary.FormOrdNumb;
                                for (int ord = 0; ord < session[bar].Orders; ord++)
                                {
                                    if (session[bar].Order[ord].OrdIf != number) continue;
                                    session[bar].Order[ord].OrdDir = session[bar].Summary.PosDir == PosDirection.Long
                                                                         ? OrderDirection.Sell
                                                                         : OrderDirection.Buy;
                                    break;
                                }
                            }
                            break;
                    }
                }
            }

            session[bar].SetWayPoint(price, wayPointType);
            if (order.OrdStatus == OrderStatus.Cancelled)
            {
                session[bar].WayPoint[session[bar].WayPoints - 1].OrdNumb = order.OrdNumb;
            }
        }