Forex_Strategy_Builder.Backtester.ExecOrd C# (CSharp) Method

ExecOrd() static private method

Tunes and Executes an order
static private ExecOrd ( int bar, Order order, double price, BacktestEval testEval ) : OrderStatus
bar int
order Order
price double
testEval BacktestEval
return OrderStatus
        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)
                    {   // The Close strategy 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 (order.OrdSender == OrderSender.Open && order.OrdStatus == OrderStatus.Confirmed)
            {
                foreach (IndicatorSlot slot in Strategy.Slot)
                    if (slot.IndicatorName == "Enter Once")
                    {
                        bool toCancel = false;
                        switch (slot.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":
                                toCancel = (Time[bar].DayOfWeek >= lastEntryTime.DayOfWeek && Time[bar] < lastEntryTime.AddDays(7));
                                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
                            break;
                        }
                        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;
        }