示例#1
0
 static public void Initialize()
 {
     using (var db = new CouatlContext())
     {
         db.Database.Migrate();
     }
 }
示例#2
0
        static public List <Account> GetAccounts(bool openOnly)
        {
            // TODO: Figure out why this statement is needed.
            // If I don't get the list of Securities here, the Transactions
            // collection of the Account will have null for the Security.
            List <Account> theList;

            using (var db = new CouatlContext())
            {
                List <Security> secList = db.Securities.ToList();
                if (openOnly)
                {
                    theList = db.Accounts
                              .Where(a => a.Closed == false)
                              .Include(a => a.Transactions)
                              .Include(a => a.Positions)
                              .ToList();
                }
                else
                {
                    theList = db.Accounts
                              .Include(a => a.Transactions)
                              .Include(a => a.Positions)
                              .ToList();
                }
            }
            return(theList);
        }
示例#3
0
 /// <summary>
 /// Add an account to the database.
 /// </summary>
 /// <param name="acct">The account to add to the database.</param>
 static public void AddAccount(Account acct)
 {
     using (var db = new CouatlContext())
     {
         db.Accounts.Add(acct);
         db.SaveChanges();
     }
 }
示例#4
0
 static public void AddSecurity(Security sec)
 {
     using (var db = new CouatlContext())
     {
         db.Securities.Add(sec);
         db.SaveChanges();
     }
 }
示例#5
0
 static public void DeleteSecurity(Security sec)
 {
     using (var db = new CouatlContext())
     {
         db.Securities.Attach(sec);
         db.Securities.Remove(sec);
         db.SaveChanges();
     }
 }
示例#6
0
 static private void UpdatePosition(Position pos)
 {
     using (var db = new CouatlContext())
     {
         db.Positions.Attach(pos);
         db.Entry(pos).State = EntityState.Modified;
         db.SaveChanges();
     }
 }
示例#7
0
 static private void DeletePosition(Position thePos)
 {
     using (var db = new CouatlContext())
     {
         db.Positions.Attach(thePos);
         db.Remove(thePos);
         db.SaveChanges();
     }
 }
示例#8
0
 // TODO: Make this private because the user should be doing delete/add; it is too difficult to change Type.
 static private void UpdateTransaction(Transaction xact)
 {
     using (var db = new CouatlContext())
     {
         db.Transactions.Attach(xact);
         db.Entry(xact).State = EntityState.Modified;
         db.SaveChanges();
     }
 }
示例#9
0
 static public void UpdateAccount(Account acct)
 {
     using (var db = new CouatlContext())
     {
         db.Accounts.Attach(acct);
         db.Entry(acct).State = EntityState.Modified;
         db.SaveChanges();
     }
 }
示例#10
0
 static public void DeleteAccount(Account acct)
 {
     using (var db = new CouatlContext())
     {
         db.Accounts.Attach(acct);
         db.Remove(acct);
         db.SaveChanges();
     }
 }
示例#11
0
        /// <summary>
        /// Returns all of the Price records in the database.
        /// </summary>
        /// <returns>List<Price> containing all Prices in the database.</Price></returns>
        static public List <Price> GetPrices()
        {
            List <Price> prices;

            using (var db = new CouatlContext())
            {
                prices = db.Prices.ToList();
            }
            return(prices);
        }
示例#12
0
        static public List <Position> GetPositions()
        {
            List <Position> theList;

            using (var db = new CouatlContext())
            {
                theList = db.Positions
                          .ToList();
            }
            return(theList);
        }
示例#13
0
        static public List <Security> GetSecurities()
        {
            List <Security> theList;

            using (var db = new CouatlContext())
            {
                theList = db.Securities
                          .ToList();
            }
            return(theList);
        }
示例#14
0
        static public List <Transaction> GetTransactions()
        {
            List <Transaction> theList;

            using (var db = new CouatlContext())
            {
                theList = db.Transactions
                          .Include(t => t.Account).ThenInclude(a => a.Positions)
                          .ToList();
            }
            return(theList);
        }
示例#15
0
        static public void AddPrice(int securityId, DateTime date, decimal amount, bool closing)
        {
            Price thePrice = new Price();

            thePrice.Amount     = amount;
            thePrice.Date       = date;
            thePrice.Closing    = closing;
            thePrice.SecurityId = securityId;

            using (var db = new CouatlContext())
            {
                bool addNewPrice = true;

                // Check for existing price.
                List <Price> prices;
                prices = db.Prices.Where(p => p.SecurityId == securityId && p.Date == date).ToList();

                // If there is more than one price for this date, then the database is in an invalid state.
                // TODO: Gracefully handle more than one price per date?
                if (prices.Count > 1)
                {
                    throw new IndexOutOfRangeException();
                }
                else if (prices.Count == 1)
                {
                    // Remove the existing price, if necessary.
                    // A non-closing price will always be removed in favor of a more-recent price.
                    // A closing price will only be removed if the new price is also a closing price
                    // (presumanly this means that the earlier closing price was incorrect).
                    if (!prices[0].Closing || closing)
                    {
                        db.Attach(prices[0]);
                        db.Remove(prices[0]);
                    }
                    else
                    {
                        addNewPrice = false;
                    }
                }

                if (addNewPrice)
                {
                    db.Prices.Add(thePrice);
                }

                db.SaveChanges();
            }
        }
示例#16
0
        static public decimal GetPrice(int secId, DateTime date)
        {
            decimal      price = 0;
            List <Price> prices;

            using (var db = new CouatlContext())
            {
                if (db.Securities.Find(secId) != null)
                {
                    prices = db.Prices.Where(p => p.SecurityId == secId && p.Date == date).ToList();
                    if (prices.Count > 0)
                    {
                        price = prices[0].Amount;
                    }
                }
            }
            return(price);
        }
示例#17
0
        static public decimal GetNewestPrice(int id)
        {
            decimal      price  = 0;
            List <Price> Prices = null;

            // Get the prices for the security.
            using (var db = new CouatlContext())
            {
                if (db.Securities.Find(id) != null)
                {
                    Prices = db.Prices.Where(p => p.SecurityId == id).ToList();
                }
            }

            // If the id is bad, then throw an exception.
            if (Prices == null)
            {
                throw new ArgumentException();
            }

            // If there are no prices yet for this security, return 0.
            // Otherwise return the most recent value.
            if (Prices.Count > 0)
            {
                // Sort by date.
                Prices.Sort((x, y) => DateTime.Compare(x.Date, y.Date));

                //TODO: Is it possible to have multiple prices for the same date?
                // If so, prefer closing to not-closing. However, it might be that
                // the Add-Price action will take care of this for us.

                // Grab the price value of the list item in the list.
                price = Prices.Last().Amount;
            }

            return(price);
        }
示例#18
0
        static public string GetSecurityNameFromId(int id)
        {
            // $$INVALID$$ means id <= 0.
            // $$NONE$$ means id is not in the db.
            string name = "$$INVALID$$";

            if (id > 0)
            {
                using (var db = new CouatlContext())
                {
                    List <Security> sec = db.Securities.Where(s => s.SecurityId == id).ToList();
                    if (sec.Count == 1)
                    {
                        name = sec[0].Name;
                    }
                    else
                    {
                        name = "$$NONE$$";
                    }
                }
            }

            return(name);
        }
示例#19
0
        public static void AddTransaction(Account theAcct, Transaction theXact)
        {
            // TODO: Data validation here? What to do if there is a problem?
            // TODO: Or, create a new Transaction object based on the input, and have the xtor do the data validation.

            using (var db = new CouatlContext())
            {
                Position thePos;
                // TODO: Update Positions here if this is a Buy/Sell/StockSplit?
                switch (theXact.Type)
                {
                case (int)TransactionType.Buy:
                    // Update Positions.
                    thePos = db.Positions.FirstOrDefault(p => p.AccountId == theAcct.AccountId && p.SecurityId == theXact.SecurityId);
                    if (thePos == null)
                    {
                        thePos = new Position
                        {
                            AccountId  = theAcct.AccountId,
                            SecurityId = theXact.SecurityId,
                            Quantity   = theXact.Quantity,
                        };
                        AddPosition(theAcct, thePos);
                    }
                    else
                    {
                        // Update the database.
                        thePos.Quantity += theXact.Quantity;
                        UpdatePosition(thePos);

                        // Update the Account object.
                        int idx = theAcct.Positions.FindIndex(p => p.PositionId == thePos.PositionId);
                        theAcct.Positions.RemoveAt(idx);
                        theAcct.Positions.Add(thePos);
                    }

                    // Update Cash.
                    theAcct.Cash -= theXact.Value;

                    // Update Prices.
                    ModelService.AddPrice(theXact);

                    break;

                case (int)TransactionType.Sell:
                    // Update Positions.
                    thePos = db.Positions.FirstOrDefault(p => p.AccountId == theAcct.AccountId && p.SecurityId == theXact.SecurityId);
                    if (thePos == null)
                    {
                        // TODO: For now, assume the user meant to show a short sell.
                        thePos = new Position
                        {
                            AccountId  = theAcct.AccountId,
                            SecurityId = theXact.SecurityId,
                            Quantity   = -1 * theXact.Quantity,
                        };
                        AddPosition(theAcct, thePos);
                    }
                    else
                    {
                        // Update the database.
                        thePos.Quantity -= theXact.Quantity;
                        UpdatePosition(thePos);

                        // Update the Account object.
                        int idx = theAcct.Positions.FindIndex(p => p.PositionId == thePos.PositionId);
                        theAcct.Positions.RemoveAt(idx);
                        theAcct.Positions.Add(thePos);
                    }

                    // Update Cash.
                    theAcct.Cash += theXact.Value;

                    // Update Prices.
                    ModelService.AddPrice(theXact);

                    break;

                case (int)TransactionType.Deposit:
                    // Update Cash.
                    theAcct.Cash += theXact.Value;

                    // Set the invalid fields for this type to default values.
                    theXact.Quantity   = 0;
                    theXact.SecurityId = -1;
                    break;

                case (int)TransactionType.Withdrawal:
                    // Update Cash.
                    theAcct.Cash -= theXact.Value;

                    // Set the invalid fields for this type to default values.
                    theXact.Quantity   = 0;
                    theXact.SecurityId = -1;
                    break;

                case (int)TransactionType.Fee:
                    // Update Cash.
                    theAcct.Cash -= theXact.Value;

                    // Set the invalid fields for this type to default values.
                    theXact.Quantity   = 0;
                    theXact.SecurityId = -1;
                    theXact.Fee        = 0;                      // It doesn't make sense to have a fee on a fee.
                    break;
                }
            }

            // Give the transaction to its account.
            theAcct.Transactions.Add(theXact);
            UpdateAccount(theAcct);
        }
示例#20
0
        static public void DeleteTransaction(Transaction theXact)
        {
            int     theAcctId = theXact.Account.AccountId;
            Account theAcct   = theXact.Account;

            // TODO: Data validation here? What to do if there is a problem?

            Position thePos;

            // TODO: Update Positions here if this is a StockSplit?
            switch (theXact.Type)
            {
            case (int)TransactionType.Buy:
                // Find the Position that this Buy affects.
                thePos = theAcct.Positions.Find(p => p.SecurityId == theXact.SecurityId);

                // Back out the shares that were added.
                thePos.Quantity -= theXact.Quantity;

                if (thePos.Quantity == 0)
                {
                    DeletePosition(thePos);
                }
                else
                {
                    UpdatePosition(thePos);
                }
                break;

            case (int)TransactionType.Sell:
                // Find the Position that this Sell affects.
                thePos = theAcct.Positions.Find(p => p.SecurityId == theXact.SecurityId);

                // Add back the shares that were removed.
                thePos.Quantity += theXact.Quantity;

                // TODO: Revisit the handling of short sells.
                // It is possible that this Sell transaction was the only one for this position.
                // In that case then we want to delete the entry in the Position table.
                if (thePos.Quantity == 0)
                {
                    DeletePosition(thePos);
                }
                else
                {
                    UpdatePosition(thePos);
                }
                break;

            case (int)TransactionType.Deposit:
                // Update Cash.
                theAcct.Cash -= theXact.Value;
                UpdateAccount(theAcct);
                break;

            case (int)TransactionType.Withdrawal:
                // Update Cash.
                theAcct.Cash += theXact.Value;
                UpdateAccount(theAcct);
                break;
            }

            // Delete the transaction from the database table.
            using (var db = new CouatlContext())
            {
                // TODO: Figure out if Attach is really needed before Remove; it seems it is not.
                //db.Transactions.Attach(theXact);
                db.Transactions.Remove(theXact);
                db.SaveChanges();
            }
        }