/// <summary>
        /// Random Execution Method
        /// </summary>
        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];
            Random 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
                    int upRange = (int)Math.Round((high - current) / Data.InstrProperties.Point);
                    int downRange = (int)Math.Round((current - low) / Data.InstrProperties.Point);
                    upRange = upRange < 0 ? 0 : upRange;
                    downRange = downRange < 0 ? 0 : downRange;
                    if (downRange + downRange == 0)
                    {
                        upRange   = 1;
                        downRange = 1;
                    }
                    int iRandom = random.Next(upRange + downRange);
                    bool bHitHigh = false;

                    if (upRange > downRange)
                        bHitHigh = iRandom > upRange;
                    else
                        bHitHigh = iRandom < downRange;

                    if (bHitHigh)
                    {   // 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
                    int iUpRange = (int)Math.Round((thePrice - current) / Data.InstrProperties.Point);
                    int iDnRange = (int)Math.Round((current - low) / Data.InstrProperties.Point);
                    iUpRange = iUpRange < 0 ? 0 : iUpRange;
                    iDnRange = iDnRange < 0 ? 0 : iDnRange;
                    if (iDnRange + iDnRange == 0)
                    {
                        iUpRange = 1;
                        iDnRange = 1;
                    }
                    int iRandom = random.Next(iUpRange + iDnRange);
                    bool executeUpper = false;

                    if (iUpRange > iDnRange)
                        executeUpper = iRandom > iUpRange;
                    else
                        executeUpper = iRandom < 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
                    int upRange   = (int)Math.Round((high - current) / Data.InstrProperties.Point);
                    int downRange = (int)Math.Round((current - thePrice) / Data.InstrProperties.Point);
                    upRange   = upRange   < 0 ? 0 : upRange;
                    downRange = downRange < 0 ? 0 : downRange;
                    if (downRange + downRange == 0)
                    {
                        upRange   = 1;
                        downRange = 1;
                    }
                    int iRandom = random.Next(upRange + downRange);
                    bool executeUpper = false;

                    if (upRange > downRange)
                        executeUpper = iRandom > upRange;
                    else
                        executeUpper = iRandom < 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
                    int upRange   = (int)Math.Round((priceHigher - current) / Data.InstrProperties.Point);
                    int downRange = (int)Math.Round((current - priceLower) / Data.InstrProperties.Point);
                    upRange   = upRange   < 0 ? 0 : upRange;
                    downRange = downRange < 0 ? 0 : downRange;
                    if (downRange + downRange == 0)
                    {
                        upRange   = 1;
                        downRange = 1;
                    }
                    int iRandom = random.Next(upRange + downRange);
                    bool executeUpper = false;

                    if (upRange > downRange)
                        executeUpper = iRandom > upRange;
                    else
                        executeUpper = iRandom < 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)
                    {
                        int upRange   = (int)Math.Round((priceHigher - current) / Data.InstrProperties.Point);
                        int downRange = (int)Math.Round((close - current) / Data.InstrProperties.Point);
                        upRange   = upRange   < 0 ? 0 : upRange;
                        downRange = downRange < 0 ? 0 : downRange;
                        if (downRange + downRange == 0)
                        {
                            upRange   = 1;
                            downRange = 0;
                        }
                        int iRandom = random.Next(upRange + downRange);

                        if (iRandom > 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
                        int upRange   = (int)Math.Round((current - close) / Data.InstrProperties.Point);
                        int downRange = (int)Math.Round((current - priceLower) / Data.InstrProperties.Point);
                        upRange   = upRange   < 0 ? 0 : upRange;
                        downRange = downRange < 0 ? 0 : downRange;
                        if (downRange + downRange == 0)
                        {
                            upRange   = 0;
                            downRange = 1;
                        }
                        int iRandom = random.Next(upRange + downRange);

                        if (iRandom > 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;
                        }
                    }
                }
            }

            return;
        }
示例#2
0
        /// <summary>
        /// Makes a deep copy.
        /// </summary>
        public Order Copy()
        {
            Order order = new Order();

            order.ordDir    = this.ordDir;
            order.ordType   = this.ordType;
            order.ordCond   = this.ordCond;
            order.ordStatus = this.ordStatus;
            order.ordSender = this.ordSender;
            order.ordOrigin = this.ordOrigin;
            order.ordNumb   = this.ordNumb;
            order.ordIF     = this.ordIF;
            order.ordPos    = this.ordPos;
            order.ordLots   = this.ordLots;
            order.ordPrice  = this.ordPrice;
            order.ordPrice2 = this.ordPrice2;
            order.ordNote   = this.ordNote;

            return order;
        }
        /// <summary>
        /// Nearest order first Method
        /// </summary>
        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;
                    }
                }
            }

            return;
        }
        /// <summary>
        /// Optimistic / Pessimistic Method
        /// </summary>
        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
                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;

                    if (current < low + micron)
                        goUpward = false;
                    else if (thePrice - current < micron)
                        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 - micron)
                        goUpward = true;
                    else if (current - thePrice < micron)
                        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 < micron)
                        executeUpper = true;
                    else if (current - priceLower < micron)
                        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 (Data.Strategy.OppSignalAction == OppositeDirSignalAction.Reverse)
                                executeUpper = !executeUpper;
                        }
                        else
                        {
                            if (current < close)
                                executeUpper = !isOptimistic;
                            else
                                executeUpper = isOptimistic;

                            if (Data.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;
                        }
                    }
                }
            }

            return;
        }
        /// <summary>
        /// Tick Scanning
        /// </summary>
        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 = Data.TickData[bar].Length;
                    for (int tick = reachedTick; tick < tickCount; tick++)
                    {
                        reachedTick = tick;
                        if (Data.TickData[bar][tick] + micron > high)
                        {   // Top found
                            current = high;
                            session[bar].SetWayPoint(high, WayPointType.High);
                            session[bar].IsTopReached = true;
                            isScanningResult = true;
                            break;
                        }
                        else if (Data.TickData[bar][tick] - micron < 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 = Data.TickData[bar].Length;
                    for (int tick = reachedTick; tick < tickCount; tick++)
                    {
                        reachedTick = tick;
                        if (Data.TickData[bar][tick] + micron > 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 = Data.TickData[bar].Length;
                    for (int tick = reachedTick; tick < tickCount; tick++)
                    {
                        reachedTick = tick;
                        if (Data.TickData[bar][tick] - micron < 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 = Data.TickData[bar].Length;
                    for (int tick = reachedTick; tick < tickCount; tick++)
                    {
                        reachedTick = tick;
                        if (Data.TickData[bar][tick] + micron > thePrice)
                        {   // The order is reached
                            current = thePrice;
                            ExecOrd(bar, theOrder, thePrice, BacktestEval.Correct);
                            isScanningResult = true;
                            break;
                        }
                        else if (Data.TickData[bar][tick] - micron < 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 = Data.TickData[bar].Length;
                    for (int tick = reachedTick; tick < tickCount; tick++)
                    {
                        reachedTick = tick;
                        if (Data.TickData[bar][tick] + micron > high)
                        {   // The Top is reached
                            current = high;
                            session[bar].SetWayPoint(high, WayPointType.High);
                            session[bar].IsTopReached = true;
                            isScanningResult = true;
                            break;
                        }
                        else if (Data.TickData[bar][tick] - micron < thePrice)
                        {   // The order is reached
                            current = thePrice;
                            ExecOrd(bar, theOrder, thePrice, BacktestEval.Correct);
                            isScanningResult = true;
                            break;
                        }
                    }
                }
                else
                {   // Execute the order
                    double priceOld = Data.TickData[bar][reachedTick];
                    int tickCount = Data.TickData[bar].Length;
                    for (int tick = reachedTick; tick < tickCount; tick++)
                    {
                        reachedTick = tick;
                        if (priceOld - micron < thePrice && Data.TickData[bar][tick] + micron > thePrice ||
                            priceOld + micron > thePrice && Data.TickData[bar][tick] - micron < 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 = Data.TickData[bar].Length;
                    for (int tick = reachedTick; tick < tickCount; tick++)
                    {
                        reachedTick = tick;
                        if (Data.TickData[bar][tick] + micron > priceHigher)
                        {   // Upper order is reached
                            current = priceHigher;
                            ExecOrd(bar, orderHigher, priceHigher, BacktestEval.Correct);
                            isScanningResult = true;
                            break;
                        }
                        else if (Data.TickData[bar][tick] - micron < priceLower)
                        {   // Lower order is reached
                            current = priceLower;
                            ExecOrd(bar, orderLower, priceLower, BacktestEval.Correct);
                            isScanningResult = true;
                            break;
                        }
                    }
                }
                else
                {   // Execute or exit the bar
                    Order  theOrder = null;
                    double thePrice = 0.0;
                    if (isHigherPrice)
                    {
                        theOrder = orderHigher;
                        thePrice = priceHigher;
                    }
                    else if (isLowerPrice)
                    {
                        theOrder = orderLower;
                        thePrice = priceLower;
                    }

                    bool executeOrder = false;
                    if (isHigherPrice)
                    {
                        int tickCount = Data.TickData[bar].Length;
                        for (int tick = reachedTick; tick < tickCount; tick++)
                        {
                            reachedTick = tick;
                            if (Data.TickData[bar][tick] + micron > thePrice)
                            {   // The order is reached
                                executeOrder = true;
                                break;
                            }
                        }
                    }
                    else if (isLowerPrice)
                    {   // The priceLower or Exit the bar
                        int tickCount = Data.TickData[bar].Length;
                        for (int tick = reachedTick; tick < tickCount; tick++)
                        {
                            reachedTick = tick;
                            if (Data.TickData[bar][tick] - micron < 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;
        }
        /// <summary>
        /// Intrabar Scanning
        /// </summary>
        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 < Data.IntraBarBars[bar]; intraBar++)
                    {
                        reachedIntrabar = intraBar;

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

                        if (Data.IntraBarData[bar][intraBar].Low - micron < low)
                        {   // Bottom found
                            if (isScanningResult)
                            {   // Top and Bottom into the same intrabar
                                isScanningResult = false;
                                break;
                            }
                            goUpward = false;
                            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 < Data.IntraBarBars[bar]; intraBar++)
                    {
                        reachedIntrabar = intraBar;

                        if (Data.IntraBarData[bar][intraBar].High + micron > 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 < Data.IntraBarBars[bar]; intraBar++)
                    {
                        reachedIntrabar = intraBar;

                        if (Data.IntraBarData[bar][intraBar].Low - micron < 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 < Data.IntraBarBars[bar]; intraBar++)
                    {
                        reachedIntrabar = intraBar;

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

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

                        if (isScanningResult)
                            break;
                    }

                    if (isScanningResult)
                    {
                        if (goUpward)
                        {   // Execute
                            if (tradedIntrabar == reachedIntrabar)
                            {
                                isScanningResult = false;
                                return isScanningResult;
                            }
                            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 < Data.IntraBarBars[bar]; intraBar++)
                    {
                        reachedIntrabar = intraBar;

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

                        if (Data.IntraBarData[bar][intraBar].Low - micron < 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
                            goUpward = false;
                            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)
                            {
                                isScanningResult = false;
                                return isScanningResult;
                            }
                            current = thePrice;
                            ExecOrd(bar, theOrder, thePrice, eval);
                            tradedIntrabar = reachedIntrabar;
                        }
                    }
                }
                else
                {   // Execute the order
                    for (int intraBar = reachedIntrabar; intraBar < Data.IntraBarBars[bar]; intraBar++)
                    {
                        reachedIntrabar = intraBar;

                        if (Data.IntraBarData[bar][intraBar].High + micron > thePrice &&
                            Data.IntraBarData[bar][intraBar].Low  - micron < thePrice)
                        {   // Order reached
                            if (tradedIntrabar == reachedIntrabar)
                            {
                                isScanningResult = false;
                                return isScanningResult;
                            }
                            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 < Data.IntraBarBars[bar]; intraBar++)
                    {
                        reachedIntrabar = intraBar;

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

                        if (Data.IntraBarData[bar][intraBar].Low - micron < priceLower)
                        {   // Lower order is reached
                            if (isScanningResult)
                            {   // Top and Bottom into the same intrabar
                                isScanningResult = false;
                                break;
                            }
                            executeUpper = false;
                            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)
                        {
                            isScanningResult = false;
                            return isScanningResult;
                        }
                        eval = BacktestEval.Correct;
                        current = thePrice;
                        ExecOrd(bar, theOrder, thePrice, eval);
                        tradedIntrabar = reachedIntrabar;
                    }
                }
                else
                {   // Execute or exit the bar
                    Order  theOrder = null;
                    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 < Data.IntraBarBars[bar]; intraBar++)
                        {
                            reachedIntrabar = intraBar;

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

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

                    if (executeOrder)
                    {   // Execute the order
                        if (tradedIntrabar == reachedIntrabar)
                        {
                            isScanningResult = false;
                            return isScanningResult;
                        }
                        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;
        }
        /// <summary>
        /// Shortest route inside the bar Method
        /// </summary>
        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 < micron)
                isGoUpward = false;
            if (isHigherPrice && priceHigher - current < micron)
                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;
                }
            }

            return;
        }
示例#8
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;
        }
 /// <summary>
 /// Finds and cancels the exit order of an entry order
 /// </summary>
 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;
         }
 }
        /// <summary>
        /// Tunes and Executes an order
        /// </summary>
        static OrderStatus ExecOrd(int bar, Order order, double price, BacktestEval testEval)
        {
            Position       position     = session[bar].Summary;
            PosDirection   posDir       = position.PosDir;
            OrderDirection ordDir       = order.OrdDir;
            WayPointType   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;
                            default:
                                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;
                            default:
                                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
                    order.OrdLots = Math.Min(TradingSize(Strategy.EntryLots, bar), 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;
                    default:
                        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;
                    default:
                        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
                    if (session[bar].Summary.Transaction == 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)
                            {
                                session[bar].Order[ord].OrdStatus = OrderStatus.Cancelled;
                                break;
                            }
                        }
                    }
                    else if (session[bar].Summary.Transaction == 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)
                            {
                                if (session[bar].Summary.PosDir == PosDirection.Long)
                                    session[bar].Order[ord].OrdDir = OrderDirection.Sell;
                                else
                                    session[bar].Order[ord].OrdDir = OrderDirection.Buy;
                                break;
                            }
                        }
                    }
                }
            }

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

            return order.OrdStatus;
        }
        /// <summary>
        /// Updates the journal data from the backtester
        /// </summary>
        void UpdateJournalData()
        {
            if (!Data.IsResult)
                return;

            Order[] aOrders = new Order[orders];
            aiOrderIcons = new Image[orders];

            int ordIndex = 0;
            for (int point = 0; point < Backtester.WayPoints(selectedBar); point++)
            {
                int iOrdNumber = Backtester.WayPoint(selectedBar, point).OrdNumb;
                WayPointType wpType = Backtester.WayPoint(selectedBar, point).WPType;

                if (iOrdNumber == -1) continue; // There is no order
                if (iOrdNumber < Backtester.OrdNumb(selectedBar, 0)) continue; // For a transferred position

                if (wpType == WayPointType.Add    || wpType == WayPointType.Cancel ||
                    wpType == WayPointType.Entry  || wpType == WayPointType.Exit   ||
                    wpType == WayPointType.Reduce || wpType == WayPointType.Reverse)
                {
                    aOrders[ordIndex] = Backtester.OrdFromNumb(iOrdNumber);
                    ordIndex++;
                }
            }

            for (int ord = 0; ord < orders; ord++)
            {
                int  ordNumber  = Backtester.OrdNumb(selectedBar, ord);
                bool toIncluded = true;
                for (int i = 0; i < ordIndex; i++)
                {
                    if (ordNumber == aOrders[i].OrdNumb)
                    {
                        toIncluded = false;
                        break;
                    }
                }
                if (toIncluded)
                {
                    aOrders[ordIndex] = Backtester.OrdFromNumb(ordNumber);
                    ordIndex++;
                }
            }

            asJournalData = new string[orders, columns];

            for (int ord = firstOrd; ord < firstOrd + shownOrd; ord++)
            {
                int row = ord - firstOrd;

                string ordIF     = (aOrders[ord].OrdIF     > 0 ? (aOrders[ord].OrdIF + 1).ToString() : "-");
                string ordPrice2 = (aOrders[ord].OrdPrice2 > 0 ? aOrders[ord].OrdPrice2.ToString(Data.FF) : "-");

                asJournalData[row, 0] = (aOrders[ord].OrdNumb + 1).ToString();
                asJournalData[row, 1] = Language.T(aOrders[ord].OrdDir.ToString());
                asJournalData[row, 2] = Language.T(aOrders[ord].OrdType.ToString());
                if (Configs.AccountInMoney)
                {
                    string sOrdAmount = (aOrders[ord].OrdDir == OrderDirection.Sell ? "-" : "") +
                                        (aOrders[ord].OrdLots * Data.InstrProperties.LotSize).ToString();
                    asJournalData[row, 3] = sOrdAmount;
                }
                else
                    asJournalData[row, 3] = aOrders[ord].OrdLots.ToString();
                asJournalData[row, 4] = aOrders[ord].OrdPrice.ToString(Data.FF);
                asJournalData[row, 5] = ordPrice2;
                asJournalData[row, 6] = Language.T(aOrders[ord].OrdStatus.ToString());
                asJournalData[row, 7] = aOrders[ord].OrdNote;

                // Icons
                aiOrderIcons[row] = aOrders[ord].OrderIcon;
            }

            return;
        }