public OrderStatusType PlaceSellOrder(StockQuote quote, double price, double volume)
        {
            if (!OpenedPositions.TryGetValue(quote.Ticker, out var openedPosition))
            {
                return(OrderStatusType.DeniedNoOpenPosition);
            }

            if (!price.InOpenRange(quote.Low, quote.High))
            {
                return(OrderStatusType.DeniedOutOfRange);
            }

            if (volume >= openedPosition.Volume)
            {
                volume = openedPosition.Volume;
                OpenedPositions.Remove(quote.Ticker);
            }
            else
            {
                openedPosition.Decrease(volume);
            }

            TheLedger.Add(new StockTransaction
            {
                Ticker          = quote.Ticker,
                Date            = quote.DateParsed,
                Price           = price,
                Volume          = volume,
                TransactionType = StockTransactionType.Sell
            });

            UpdateBalance(price, volume, StockTransactionType.Sell);

            return(OrderStatusType.Accepted);
        }
        public int Solve()
        {
            int n2 = N * 2;

            int[,] result = new int[n2 + 1, N + 1];

            for (int i = 1; i <= N; i++)
            {
                result[n2, i] = 0;
            }
            result[n2, 0] = 1;

            for (int position = n2 - 1; position >= 0; position--)
            {
                for (int opened = 0; opened <= N; opened++)
                {
                    result[position, opened] = 0;

                    if (opened > 0 && !OpenedPositions.Contains(position))
                    {
                        result[position, opened] += result[position + 1, opened - 1];
                    }

                    if (opened < N)
                    {
                        result[position, opened] += result[position + 1, opened + 1];
                    }
                }
            }

            return(result[0, 0]);
        }
        public OrderStatusType PlaceBuyOrder(StockQuote quote, double price, double volume)
        {
            if (Balance * 1.001 <= price * volume)
            {
                return(OrderStatusType.DeniedInsufficientFunds);
            }
            if (!price.InOpenRange(quote.Low, quote.High))
            {
                return(OrderStatusType.DeniedOutOfRange);
            }

            var isPositionOpened = OpenedPositions.ContainsKey(quote.Ticker);
            var newPosition      = new OpenedPosition {
                Price = price, Volume = volume
            };

            if (isPositionOpened)
            {
                OpenedPositions[quote.Ticker] += newPosition;
            }
            else
            {
                OpenedPositions.Add(quote.Ticker, newPosition);
            }

            TheLedger.Add(new StockTransaction
            {
                Ticker          = quote.Ticker,
                Date            = quote.DateParsed,
                Price           = price,
                Volume          = volume,
                TransactionType = StockTransactionType.Buy
            });

            UpdateBalance(price, volume, StockTransactionType.Buy);

            return(OrderStatusType.Accepted);
        }