Example #1
0
        /// <summary>
        /// Simulate a day in the market.
        /// </summary>
        public void Simulate()
        {
            if (CurrentDate != EndDate)
            {
                CurrentDate = CurrentDate.AddDays(1);
                StockDay    = DataManager.IsStockDay(CurrentDate);

                // before we even bother with any calculations, we need to
                // make sure the stock market was open on this given day
                if (StockDay)
                {
                    UpdateMarketState();
                    StockDays.Add(CurrentDate);
                    Log("Stockday on " + CurrentDate + ", proceeding...");

                    // how has our equity changed over postmarket and premarket
                    for (int i = 0; i < Positions.Count; i++)
                    {
                        List <BarData> history = MarketState.FirstOrDefault(x => x.Key == Positions[i].Symbol).Value;

                        // how much has the stock changed in value overnight?
                        double change = history.Last().Open - history[history.Count - 2].Close;

                        // change our equity!
                        Equity += change * Positions[i].Shares;
                    }

                    // process orders
                    ProcessAllOrders();

                    // with our new positions, how will our equity change today?
                    for (int i = 0; i < Positions.Count; i++)
                    {
                        List <BarData> history = MarketState.FirstOrDefault(x => x.Key == Positions[i].Symbol).Value;

                        // how much has the stock changed in value overnight?
                        double change = history.Last().Close - history.Last().Open;

                        // change our equity!
                        Equity += change * Positions[i].Shares;

                        // update the position value
                        Positions[i].PriceHistory.Add(new Tuple <DateTime, double, double>(CurrentDate, history.Last().Close, change));
                    }

                    // allow the strategy to make calls for the next day
                    Strategy.Update(this);

                    // process all logs for the day
                    ProcessLogs();
                }

                EquityHistory.Add(new Tuple <DateTime, double>(CurrentDate, Equity));
                BuyingPowerHistory.Add(new Tuple <DateTime, double>(CurrentDate, BuyingPower));
            }
            else
            {
                throw new Exception("Simulation is already complete.");
            }
        }
Example #2
0
        /// <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]);
                    }
                }
            }
        }