コード例 #1
0
ファイル: Account.cs プロジェクト: tareqalyousef/backtester
        /// <summary>
        /// Place a box order.
        /// </summary>
        public void PlaceBoxOrderSell(string symbol, int shares, double lowerLimit, double upperLimit)
        {
            // we cannot place box orders when we have regular orders
            foreach (Order order in Orders)
            {
                if (order.Symbol == symbol && order.ActionType == ActionType.Sell)
                {
                    throw new Exception("Cannot make box order for stock " + symbol);
                }
            }

            // do we even have this many shares?
            int owned = 0;

            foreach (Position pos in Positions)
            {
                if (pos.Symbol == symbol)
                {
                    owned += pos.Shares;
                }
            }

            // how many sells do we already have?
            int ownedSells = 0;

            foreach (BoxOrder order in BoxOrders)
            {
                if (order.Symbol == symbol)
                {
                    ownedSells += order.Shares;
                }
            }

            if (shares <= (owned - ownedSells))
            {
                BoxOrders.Add(new BoxOrder(ActionType.Sell, symbol, CurrentDate, shares, lowerLimit, upperLimit));
            }
            else
            {
                throw new Exception("Cannot place box order for " + shares + " shares of " + symbol);
            }
        }
コード例 #2
0
ファイル: Account.cs プロジェクト: tareqalyousef/backtester
 /// <summary>
 /// Cancel all box orders.
 /// </summary>
 public void CancelBoxOrders()
 {
     BoxOrders.Clear();
 }
コード例 #3
0
ファイル: Account.cs プロジェクト: tareqalyousef/backtester
        /// <summary>
        /// Processes orders and box orders.
        /// </summary>
        private void ProcessAllOrders()
        {
            // now, what orders were placed overnight?
            for (int i = 0; i < Orders.Count; i++)
            {
                List <BarData> history = MarketState.FirstOrDefault(x => x.Key == Orders[i].Symbol).Value;

                if (Orders[i].ActionType == ActionType.Buy)
                {
                    if (Orders[i].OrderType == OrderType.Limit)
                    {
                        double realBuyPrice = -1;

                        // has the stocks price gone over or below the limit price today?
                        if (history.Last().High >= Orders[i].LimitPrice &&
                            history.Last().Low <= Orders[i].LimitPrice)
                        {
                            realBuyPrice = Orders[i].LimitPrice;
                        }
                        else if (Orders[i].LimitPrice <history.Last().Open&& Orders[i].LimitPrice> history[history.Count - 2].High)
                        {
                            realBuyPrice = history.Last().Open;
                        }
                        else if (Orders[i].LimitPrice > history.Last().Open&& Orders[i].LimitPrice < history[history.Count - 2].Low)
                        {
                            realBuyPrice = history.Last().Open;
                        }

                        if (realBuyPrice != -1)
                        {
                            // if so, can we afford to buy this many shares?
                            if (Orders[i].LimitPrice * Orders[i].Shares <= BuyingPower)
                            {
                                // buy the shares!
                                BuyingPower -= realBuyPrice * Orders[i].Shares;

                                // place a position
                                Positions.Add(new Position(Orders[i].Symbol, Orders[i].Shares, realBuyPrice, CurrentDate));

                                // fire event
                                Strategy.ProcessOrder(this, Orders[i], realBuyPrice);

                                // log
                                Log("Bought " + Orders[i].Shares + " shares of " + Orders[i].Symbol + " for $" + realBuyPrice + " per share.");

                                // remove this order
                                Orders.Remove(Orders[i]);
                            }
                        }
                    }
                    else if (Orders[i].OrderType == OrderType.Market)
                    {
                        if (history.Last().Open *Orders[i].Shares <= BuyingPower)
                        {
                            // buy the shares!
                            BuyingPower -= history.Last().Open *Orders[i].Shares;

                            // place a position
                            Positions.Add(new Position(Orders[i].Symbol, Orders[i].Shares, history.Last().Open, CurrentDate));

                            // fire event
                            Strategy.ProcessOrder(this, Orders[i], history.Last().Open);

                            // log
                            Log("Bought " + Orders[i].Shares + " shares of " + Orders[i].Symbol + " for $" + history.Last().Open + " per share.");

                            // remove this order
                            Orders.Remove(Orders[i]);
                        }
                    }
                }
                else if (Orders[i].ActionType == ActionType.Sell)
                {
                    if (Orders[i].OrderType == OrderType.Limit)
                    {
                        double realSellPrice = -1;

                        // has the stocks price gone over or below the limit price today?
                        if (history.Last().High >= Orders[i].LimitPrice &&
                            history.Last().Low <= Orders[i].LimitPrice)
                        {
                            realSellPrice = Orders[i].LimitPrice;
                        }
                        else if (Orders[i].LimitPrice <history.Last().Open&& Orders[i].LimitPrice> history[history.Count - 2].High)
                        {
                            realSellPrice = history.Last().Open;
                        }
                        else if (Orders[i].LimitPrice > history.Last().Open&& Orders[i].LimitPrice < history[history.Count - 2].Low)
                        {
                            realSellPrice = history.Last().Open;
                        }

                        if (realSellPrice != -1)
                        {
                            // sell the shares!
                            BuyingPower += realSellPrice * Orders[i].Shares;
                            Equity      += (realSellPrice - history.Last().Open) * Orders[i].Shares;

                            int             toRemove          = Orders[i].Shares;
                            List <Position> positionsToRemove = new List <Position>();

                            // remove the position
                            for (int j = 0; j < Positions.Count; j++)
                            {
                                if (Positions[j].Symbol == Orders[i].Symbol)
                                {
                                    if (Positions[j].BuyPrice >= realSellPrice)
                                    {
                                        Losses++;
                                    }
                                    else
                                    {
                                        Wins++;
                                    }

                                    if (Positions[j].Shares > toRemove)
                                    {
                                        Positions[j].Shares -= toRemove;
                                        break;
                                    }
                                    else if (Positions[j].Shares == toRemove)
                                    {
                                        positionsToRemove.Add(Positions[j]);
                                        break;
                                    }
                                    else if (Positions[j].Shares < toRemove)
                                    {
                                        positionsToRemove.Add(Positions[j]);
                                        toRemove -= Positions[j].Shares;
                                    }
                                }
                            }

                            foreach (Position pos in positionsToRemove)
                            {
                                Positions.Remove(pos);
                            }

                            // fire event
                            Strategy.ProcessOrder(this, Orders[i], realSellPrice);

                            // log
                            Log("Sold " + Orders[i].Shares + " shares of " + Orders[i].Symbol + " for $" + realSellPrice + " per share.");

                            // remove this order
                            Orders.Remove(Orders[i]);
                        }
                    }
                    else if (Orders[i].OrderType == OrderType.Market)
                    {
                        // sell the shares!
                        BuyingPower += history.Last().Open *Orders[i].Shares;

                        int             toRemove          = Orders[i].Shares;
                        List <Position> positionsToRemove = new List <Position>();

                        // remove the position
                        for (int j = 0; j < Positions.Count; j++)
                        {
                            if (Positions[j].Symbol == Orders[i].Symbol)
                            {
                                if (Positions[j].BuyPrice >= history.Last().Open)
                                {
                                    Losses++;
                                }
                                else
                                {
                                    Wins++;
                                }

                                if (Positions[j].Shares > toRemove)
                                {
                                    Positions[j].Shares -= toRemove;
                                    break;
                                }
                                else if (Positions[j].Shares == toRemove)
                                {
                                    positionsToRemove.Add(Positions[j]);
                                    break;
                                }
                                else if (Positions[j].Shares < toRemove)
                                {
                                    positionsToRemove.Add(Positions[j]);
                                    toRemove -= Positions[j].Shares;
                                }
                            }
                        }

                        foreach (Position pos in positionsToRemove)
                        {
                            Positions.Remove(pos);
                        }

                        // fire event
                        Strategy.ProcessOrder(this, Orders[i], history.Last().Open);

                        // log
                        Log("Sold " + Orders[i].Shares + " shares of " + Orders[i].Symbol + " for $" + history.Last().Open + " per share.");

                        // remove this order
                        Orders.Remove(Orders[i]);
                    }
                }
            }

            // now, what box orders were placed overnight?
            for (int i = 0; i < BoxOrders.Count; i++)
            {
                List <BarData> history = MarketState.FirstOrDefault(x => x.Key == BoxOrders[i].Symbol).Value;

                if (BoxOrders[i].ActionType == ActionType.Buy)
                {
                    // todo:
                }
                else if (BoxOrders[i].ActionType == ActionType.Sell)
                {
                    double realSellPrice = -1;

                    // has the stocks price gone over or below either of the limit prices today?
                    if (history.Last().High >= BoxOrders[i].UpperLimitPrice &&
                        history.Last().Low <= BoxOrders[i].UpperLimitPrice)
                    {
                        realSellPrice = BoxOrders[i].UpperLimitPrice;
                    }
                    else if (history.Last().High >= BoxOrders[i].LowerLimitPrice &&
                             history.Last().Low <= BoxOrders[i].LowerLimitPrice)
                    {
                        realSellPrice = BoxOrders[i].LowerLimitPrice;
                    }
                    else if (BoxOrders[i].UpperLimitPrice <history.Last().Open&& BoxOrders[i].UpperLimitPrice> history[history.Count - 2].High)
                    {
                        realSellPrice = history.Last().Open;
                    }
                    else if (BoxOrders[i].LowerLimitPrice <history.Last().Open&& BoxOrders[i].LowerLimitPrice> history[history.Count - 2].High)
                    {
                        realSellPrice = history.Last().Open;
                    }
                    else if (BoxOrders[i].UpperLimitPrice > history.Last().Open&& BoxOrders[i].UpperLimitPrice < history[history.Count - 2].Low)
                    {
                        realSellPrice = history.Last().Open;
                    }
                    else if (BoxOrders[i].LowerLimitPrice > history.Last().Open&& BoxOrders[i].LowerLimitPrice < history[history.Count - 2].Low)
                    {
                        realSellPrice = history.Last().Open;
                    }

                    if (realSellPrice != -1)
                    {
                        // sell the shares!
                        BuyingPower += realSellPrice * BoxOrders[i].Shares;
                        Equity      += (realSellPrice - history.Last().Open) * BoxOrders[i].Shares;

                        int             toRemove          = BoxOrders[i].Shares;
                        List <Position> positionsToRemove = new List <Position>();

                        // remove the position
                        for (int j = 0; j < Positions.Count; j++)
                        {
                            if (Positions[j].Symbol == BoxOrders[i].Symbol)
                            {
                                if (Positions[j].BuyPrice >= realSellPrice)
                                {
                                    Losses++;
                                }
                                else
                                {
                                    Wins++;
                                }

                                if (Positions[j].Shares > toRemove)
                                {
                                    Positions[j].Shares -= toRemove;
                                    break;
                                }
                                else if (Positions[j].Shares == toRemove)
                                {
                                    positionsToRemove.Add(Positions[j]);
                                    break;
                                }
                                else if (Positions[j].Shares < toRemove)
                                {
                                    positionsToRemove.Add(Positions[j]);
                                    toRemove -= Positions[j].Shares;
                                }
                            }
                        }

                        foreach (Position pos in positionsToRemove)
                        {
                            Positions.Remove(pos);
                        }

                        // fire event
                        Strategy.ProcessBoxOrder(this, BoxOrders[i], realSellPrice);

                        // log
                        Log("Sold " + BoxOrders[i].Shares + " shares of " + BoxOrders[i].Symbol + " for $" + realSellPrice + " per share.");

                        // remove this order
                        BoxOrders.Remove(BoxOrders[i]);
                    }
                }
            }
        }