コード例 #1
0
ファイル: HelperTests.cs プロジェクト: kenaschmidt/Finance
        public void TestEnumToInt()
        {
            TradeActionBuySell enum1 = TradeActionBuySell.Buy;
            PositionDirection  enum2 = PositionDirection.LongPosition;

            Assert.AreEqual(enum1.ToInt(), enum2.ToInt());
        }
コード例 #2
0
ファイル: Helpers.cs プロジェクト: kenaschmidt/Finance
        /// <summary>
        /// Calculates the average basis cost of a sequence of trades
        /// </summary>
        /// <param name="trades">Ordered list of trades. Reordered in ascending date order upon entry.</param>
        /// <param name="direction">Calculates for a long position or short.  Throws an exception if the first trade in the sequence does not match</param>
        /// <returns>The average cost per share of remaining shares at the end of the trade sequence.  Throws an exception if the position ever flips long/short</returns>
        public static decimal AverageCost(this List <Trade> trades, PositionDirection direction)
        {
            // Order the trades
            trades = new List <Trade>(trades).OrderBy(x => x.TradeDate).ToList();

            // Check direction
            if ((int)trades.FirstOrDefault().TradeActionBuySell != (int)direction)
            {
                throw new InvalidTradeForPositionException();
            }

            // Iterate through the trades and compute average cost
            int     sharesOpen  = 0;
            decimal averageCost = 0;

            foreach (var trd in trades)
            {
                // Buy trades increase position and update average price
                // Sell trades reduce position
                if (trd.TradeActionBuySell.ToInt() == direction.ToInt())
                {
                    averageCost = ((averageCost * sharesOpen) + (trd.TotalCashImpactAbsolute)) / (sharesOpen += trd.Quantity);
                }
                else if (trd.TradeActionBuySell.ToInt() == -direction.ToInt())
                {
                    sharesOpen -= trd.Quantity;
                }

                // sharesOpen should always be positive, otherwise we have flipped long/short
                if (sharesOpen < 0)
                {
                    throw new InvalidTradeForPositionException();
                }
            }

            return(Math.Round(averageCost, 3));
        }