views:

81

answers:

5

Hello,

I am making a small personal application regarding my trade of shares of various companies.

The actions can be selling shares of a company or buying. Therefore, the details to be saved in both cases would be:

  1. Number of Shares
  2. Average Price

Would it be better to use separate tables for "buy" and "sell" or just use one table for "trade" and keep a field that demarcates "buy" from "sell"?

+3  A: 

Definitely the latter case - one table, simple one field (boolean) defining whether it's selling or buying. You should define tables by entities, not by actions taken on them.

Eimantas
Then by that, I'll keep my current design. I have a boolean as "true" for buy. Thanks :)
hkansal
+2  A: 

I'd go with a single table.

You can use negative quantities to indicate a sell. This is a fairly standard sort of indication. Subtraction is the same as adding a negative number!

Matthew Scharley
Should I use only negative quantities for demarcation or a separate field too? I could not think how I would identify a record to update for a buy/sell. Initially the quantity would be zero.It would actually be nice to do away with the extra field, just getting greedy!
hkansal
+2  A: 

One table. Each row/item is a trade, whether it's buy or sell.

Also, the aggregate of the quantity column will give you your current position. And cash too (-1 x quantity x price**) aggregated.

Buy or sell if inferred by the sign of the quantity: no need for separate column, unless you want to make a computed column derived from quantity.

**cash: When you sell (negative quantity) you get cash back (positive cash), hence -1 multiplier in case anyone wonders.

gbn
Yes, I understand that. But For the very first time, quantity for both buy and sell would be zero. How will I identify which one to update, only for the very first time?
hkansal
@hkansal£: as others mentioned and I assumed, you should have one row per buy and sell with one quantity and one price column. Your model is flawed otherwise.
gbn
+3  A: 

This is actually a tricky one. The table you're talking about is basically a trade table, detailing all your buys and sells.

In that sense, you would think it would make sense to have both buys and sells in a single table.

However, in many jurisdictions, there is extra information for a sell order. That piece of information is which buy order to offset it against (for capital gains or profit purposes). While this is not necessary in a strict first-bought, first-sold (FBFS) environment, that's by no means the only possibility.

For example, under Australian law, you can actually offset a sale against your most recent purchase, as long as you have the rationale written down in clear language before-hand. Even though my company follow FBFS, I am allowed to receive bonus issues or supplemental shares which I can then sell immediately. These are offset against the most recent shares bought, not ones I've held for X number of years (this is often handy to minimise taxes payable).

If you follow a strict FBFS, then you don't need that extra information and your trades are symmetrical. Even where they're not, I've implemented it in one table with the extra information, useless for buy orders of course. That seemed the easiest way to go.

You could do it as two asymmetrical tables but that makes queries a bit more problematic since you often need to pull data from both tables. My advice is to stick with a single table with the extra information if needed.

I would also never store the average price. I prefer the quantity, the price per share and the brokerage costs. Every other figure can be calculated from those three, for example:

AvgPrice = (Brokerage + SharePrice * ShareQuant) / ShareQuant

but it's sometimes impossible to work backwards from just the average price, since you don't know what the brokerage was.

And I wouldn't have a boolean for buy/sell, it's just as easy to use negative numbers for the sell orders and it makes balance-sheet-type calculations a lot easier since you just sum values irrespective of the order type instead of needing to negate some of them depending on that order type.


Update: If, as you seem to indicate, you're only going to store aggregate information for each company, I would go for the following:

Companies:
    CompanyId primary key
    CompanyCode indexed
    CompanyName
    CompanyBuyQuant
    CompanyBuyAvgPrice
    CompanySellQuant
    CompanySellAvgPrice

then you update the individual columns depending on whether it's a buy or sell. You don't need a separate row for the buy/sell stuff. When the company is first added, both quantities and prices are set to 0.

Your entity is now the company so this makes more sense. One thing you may want to consider is to store the aggregate values of shares bought and sold rather than the average buy and sell prices. That will simplify your update calculations and you can still easily get the averages by dividing the aggregate by the quantity.

So, the following table:

Companies:
    CompanyId primary key
    CompanyCode indexed
    CompanyName
    CompanyBuyQuant
    CompanyBuyValue
    CompanySellQuant
    CompanySellValue
  • When adding a company, set all quanities and values to 0,
  • When buying M shares at N dollars each, add M to CompanyBuyQuant and N * M to CompanyBuyValue.
  • When selling M shares at N dollars each, add M to CompanySellQuant and N * M to CompanySellValue.
  • Get average buy price as CompanyBuyValue / CompanyBuyQuant.
  • Get average sell price as CompanySellValue / CompanySellQuant.
paxdiablo
That's informative. In my case, Avg Price is what you have taken as Share Price as there is no brokerage. So that is resolved.Negative quantities can be used, no doubt, but I am confused about the very first update.When a new company name would be added, 2 corresponding records would be added for that company in the trade table, 1 for buy and sell each. Both records would be identical. CompanyId: "same for both", Qty: 0, AvgPrice: 0.
hkansal
+1 for elaborating on the answer. The extra sell information could be kept in a separate table in case you need to offset a single sell against many buys.
Chris Bednarski
@hkansal, when you add a _company_ to your system, there will be _no_ buys or sells. The first time you buy _shares_ in that company (which may be the same time you add it), you will get one row (e.g., buy 100 ibm @ $128 = $12,800). You won't get a sell order until you sell them. Every trade should have it's own row and your current position re that company can be worked out by processing all those rows.
paxdiablo
I guess I am on a different page. Please let me clarify. At any time, the trade table would have only 2 rows for a company. Suppose I bought 100 shares @ 50 for company A, the row for buy records would have Qty as 100. Next buy of 50 @ 40 will update that very same row to 150 and calculate the new avg price.There is no requirement to maintain records for each buy/sell(trade or transaction) as it is being done in my trading system. This is just a personal application because the trading system forgets all records after March 31 :(
hkansal
If you're not maintaining individual trades but instead a buy and sell statement, you don't even need two rows. Just have one row for the company with buy and sell columns. I'll update my answer.
paxdiablo
Thanks a lot paxdiablo. :) I get this. Still I would like to keep a table of Company's id, code and name separate from buy/sell info where I can use a foreign key.
hkansal
+1  A: 

"Trade" can be ambiguous and it's not entirely clear to me what you want to do here. Are you interested in storing only your current position in each share or also the history of transactions that show how the position developed?

If you just want to record your holding ("position" might be a better word if you can be short) then I'd simply record for each share the number held. You mention average price, but I'd be cautious about that if you expect at any time to be able to sell part of a holding. What's the average price if you buy 100 at 50, 100 at 60 and sell 50 at 70?

Unless you expect your buy and sell transactions to number in the millions, I'd be more inclined to record each individual purchase or sale as a separate row in a single table and show the totals on demand as the derived results of a simple query.

Mike Woodhouse
Yes, I need to store only the current position, separately for buy and sell. Next, the average price would be the weighted average, calculated separately for buy and sell.
hkansal