示例#1
0
        /// <summary>
        /// Close a position. If not all shares are used, return
        /// a closed position. Modify position so that it can still be used
        /// as an open position with the remaining shares.
        /// If all shares are used, return null;
        /// </summary>
        /// <param name="position"></param>
        /// <param name="stock"></param>
        /// <param name="sharesToSell"></param>
        /// <returns></returns>
        public static Position ClosePosition(Position position, Stock stock, double sharesToSell)
        {
            position.CurrentPrice = stock.AdjustedClose;

            if (Math.Abs(sharesToSell - position.Shares) < Portfolio.Epsilon)
            {
                // all shares used up, just close this position and returns null
                // some bookkeeping
                position.SoldDate = stock.Date;
                position.Close = true;
                return null;
            }

            double remainingShares = position.Shares - sharesToSell;

            // change the position shares
            position.Shares = remainingShares;

            // now return a closed position with the shares sold

            return new Position
            {
                // acquired date is the same
                AcquiredDate = position.AcquiredDate,
                Shares = sharesToSell,
                // acquired price is also the same
                AcquiredPrice = position.AcquiredPrice,
                CurrentPrice = stock.AdjustedClose,
                Close = true,
                SoldDate = stock.Date,
                Name = stock.Name,
                Ticker = stock.Ticker
            };
        }
示例#2
0
        public static Stock ParsePrice(string price, string Ticker, string Name)
        {
            string[] values = price.Split(',');

            Stock result = new Stock();

            result.Date = DateTime.Parse(values[0]);
            result.Open = Double.Parse(values[1]);
            result.High = Double.Parse(values[2]);
            result.Low = Double.Parse(values[3]);
            result.Close = Double.Parse(values[4]);
            result.Volumn = long.Parse(values[5]);
            result.AdjustedClose = Double.Parse(values[6]);
            result.Ticker = Ticker;
            result.Name = Name;

            return result;
        }
示例#3
0
        /// <summary>
        /// Buy a stock
        /// </summary>
        /// <param name="stock"></param>
        /// <param name="ticker"></param>
        public void BuyStock(Stock stock, double money)
        {
            if (money > Cash && (Math.Abs(money - Cash) > 0.0005))
            {
                throw new InvalidOperationException("Not enough cash!");
            }

            // let's sese how many shares we can buy
            double noOfShares = (money - Commission) / stock.AdjustedClose;

            Cash = Cash - money;

            // Open a list of position if not already there
            if (!OpenPositions.ContainsKey(stock.Ticker))
            {
                OpenPositions[stock.Ticker] = new List<Position>();
            }

            // Add to the list of position
            OpenPositions[stock.Ticker].Add(Position.OpenPosition(stock, noOfShares));
        }
示例#4
0
 public void UpdateOpenPosition(Stock stock)
 {
     if (OpenPositions.ContainsKey(stock.Ticker)
         && OpenPositions[stock.Ticker] != null)
     {
         foreach (var position in OpenPositions[stock.Ticker])
         {
             position.CurrentPrice = stock.AdjustedClose;
         }
     }
 }
示例#5
0
        public void SellStock(Stock stock, double noOfShares)
        {
            if (!OpenPositions.ContainsKey(stock.Ticker))
            {
                throw new InvalidOperationException("No stock to sell!");
            }

            if (noOfShares <= Epsilon)
            {
                throw new ArgumentException(String.Format("noOfShares {0} is zero or negative", noOfShares));
            }

            // update the current price of all the open positions for this stock
            UpdateOpenPosition(stock);

            // check the total number of shares available
            double totalShares = OpenPositions[stock.Ticker].Sum(position => position.Shares);

            if (totalShares < noOfShares && Math.Abs(totalShares - noOfShares) < Epsilon)
            {
                throw new InvalidOperationException("Not enough shares to sell");
            }

            // add to the close position list
            if (!ClosedPositions.ContainsKey(stock.Ticker))
            {
                ClosedPositions[stock.Ticker] = new List<Position>();
            }

            // update cash before we sell (greedy hehe)
            Cash += ((noOfShares * stock.AdjustedClose) - Commission);

            // for now, we will sell the earliest available one first.
            // other selling method will be added in the future
            foreach (var position in OpenPositions[stock.Ticker])
            {
                // checks whether noOfShares are greater than or equal to the amount in this position
                if (noOfShares > position.Shares || Math.Abs(noOfShares - position.Shares) < Epsilon)
                {
                    // sell this position
                    // don't care about the return value here because all shares are used up
                    Position.ClosePosition(position, stock, position.Shares);

                    // decrease the share
                    noOfShares -= position.Shares;

                    // add this to the close position
                    ClosedPositions[stock.Ticker].Add(position);

                    UpdatePortfolioAfterClosingPosition(position);

                    if (noOfShares < Epsilon)
                    {
                        break;
                    }
                }
                else
                {
                    // we have enough in this position
                    Position closedPosition = Position.ClosePosition(position, stock, noOfShares);

                    UpdatePortfolioAfterClosingPosition(closedPosition);

                    ClosedPositions[stock.Ticker].Add(closedPosition);
                }
            }

            // remove the closed positions
            OpenPositions[stock.Ticker].RemoveAll(position => position.Close);
        }
示例#6
0
        public double GetStockShares(Stock stock)
        {
            if (!OpenPositions.ContainsKey(stock.Ticker) || OpenPositions[stock.Ticker] == null)
            {
                return 0;
            }

            return OpenPositions[stock.Ticker].Sum(position => position.Shares);
        }
示例#7
0
        /// <summary>
        /// Opens a position
        /// </summary>
        /// <param name="stock"></param>
        public static Position OpenPosition(Stock stock, double shares)
        {
            Position position = new Position
            {
                AcquiredDate = stock.Date,
                Shares = shares,
                AcquiredPrice = stock.AdjustedClose,
                CurrentPrice = stock.AdjustedClose,
                Name = stock.Name,
                Ticker = stock.Ticker
            };

            return position;
        }