views:

61

answers:

2

I've written a small application that deals with the private stock market. I store all data in one table (to simplify problem) with following columns:

ID, TransactionType, Quantity, Numbers From, Numbers Too, Client ID, Date
1, Buy, 100, AB1000, AB1099, 5, 2009-01-30
2, Sell, 100, AB1000, AB1099, 5, 2010-01-01
3, Buy, 40, AB500, AB539, 5, 2010-01-01

And it goes like that all the way for everyone. When my user wants to get information what the client has program sums it up for him doing + on Buy and - on Sell making sure the numbers match (on public market there is no stock numbers, on private there is). To this day it's not possible in my program to be able to sell anything partially. For example i can't sell 30 stocks if i didn't bought it before. So even thou customer may have 40 stocks, i can only sell 40 but not 30 since numbers doesn't match.

I was asked today if we can change it (they changed their original request), and I wanted to get some advice if it's really the proper way to do so:

If customer had 100 stocks then tried to sell only 30 with numbers AB1030 - AB1059 I would insert something like this in my table:

ID, TransactionType, Quantity, Numbers From, Numbers Too, Client ID
4, Split-, 100, AB1000, AB1099, 5
5, Split+, 30, AB1000, AB1029, 5
6, Split+, 30, AB1030, AB1059, 5
7, Split+, 40, AB1060, AB1099, 5
8, Sell, 30, AB1030, AB1059, 5

I could even not show this Split to user to not confuse him/her too much. Just as an addition I don't keep real time data, I keep only history in terms that I always have to recalculate everything if i want to get current information. I implemented it this way because they often use old data in terms checking current state of customer on older dates etc.

What would be your suggestion? Is this approach good one or should I totally rewrite it. Keep in mind that the system is already live so i would have to somehow migrate it over. And also it shouldn't be a total rework as i won't get payed for it most likely so don't have 6 months to fix it.

+1  A: 

Can we see a little code what you have in your Business logic and what kind restrictions you have on buying/selling stock? I guess you have to rethink your way of saying STOP to you costumers when selling different amounts. If your business need to have a restriction on selling things you haven't bought, well maybe you can't sell it (yet)? Or you can sell it only if specific rules apply.

Niike2
Well this little application is 100k lines long and has some heavy (noob) logic behind it. It's not customers who will be doing the sell / buy things but employee (1-2 ppl). Right now everything can be sold in packets, if you have bought 100 stocks you can sell 100 stocks that match their numbers, or if it isn't blocked. So the only thing they want changed is that they can split those 100 stocks as they wish so they can take 30 stocks from those 100 and just sell it. They will choose amount and numbers they want to sell. So in some cases it will match the bought earlier packet
MadBoy
and sometimes it won't, and then i will have to split those 100 stocks so that at every time i know what customer has, and what he hasn't. Numbers are the key. I know i could work with just amounts and it would be easier, but numbers has to stay and they distinguish one packet from another. Right now it works that i show a list of what customer has and employee chooses that and sells it. What they want is i guess they choose a packet and they sell half of it, and half has to stay with proper numbers.
MadBoy
Ok, but I still don't understand what part is the question, or just conversation how to solve a problem? Do you need help how to change the numbers in your objects/table i.e if(stock.amount > newSold.amount) return OutOfStockException? Or is it a SQL problem that you cant split a stock? Or is it
Niike2
Normally I would add a UpdatedBy and UpdatedWhen column in your table. Then subtract the customer.order1.item1.amount by what entered in by employee numberToSell.text!? When employee have changed the order, you update the amount and when the change happened and by who.
Niike2
More like approach problem. Is the way i described good for this situation? To enter 4 additional transactions just to be able to split 30 stocks from 100 stocks? Or there is better way. I don't need the code for this. More like approach
MadBoy
Nike2, your approach would be simple if i didn't had Stock Numbers which make it a bit harder then simple substract.
MadBoy
Well its hard to see and understand what limitations you have in your app. There is many ways to do it I guess and your way of doing a new line and maybe subtract -25items from Stock Numbers isn't so bad! Depends on how many and how often you change your Stock Numbers to something smaller/bigger. Will you flood you DB on editing when using that approach or will it only happen once in a while? If latter then maybe it dosen't do so much. Only make some "When viewed by Customer calculate total Stock +Buy -Sell, then show result" Only allow employee will see the full transactions!
Niike2
+1  A: 

It sounds to me like you should factor out the current validation logic with something that is more flexible. That is, instead of requiring the numbers to match up it might be possible to only require that the balance is 0 or positive (i.e. so you cannot sell what you do not own). To implement this I'd refactor your data storage so that you can check the owned amount as a single value rather than matching it against past transactions.

This could easily be implemented with a single query along these lines:

public void SellStock( int clientID, string stockSymbol, int quantityToSell )
{
     using( var scope = new TransactionScope() )
     {
          // pseudo-sql for reducing client portfolio by quantity
          update ClientStockPortfolio 
          set Quantity = Quantity - quantityToSell 
          where ID = clientID 
          and StockSymbol = stockSymbol
          and Quantity >= quantityToSell 

          // log transaction history and update other tables as needed
     }
}
Morten Mertner
I would also need to track stock numbers. If i don't do that user could sell same numbers twice (even if balance would be okey, numbers wouldn't). I guess having one value instead of past transactions is idea i will have to implement.
MadBoy
Shouldn't your balance alone be verification enough? I don't think your bank tries to validate your withdrawals against any past deposits :) That said, you could have business specific requirements for additional validation. I'd recommend keeping a transaction log (in a table) and extend the where clause to make the necessary checks (or do it in code if they're hard to implement in SQL or whatever you're using as the data layer).
Morten Mertner
Well bank doesn't care if i put money in with 100$ or 20$. In the end it's 120$. In private stocks you can't have 2 packets with same numbers. For example 100 stocks with AB123 to AB222. You can't have that 2 times, and you can't sell that twice. So numbers are mimportant.
MadBoy