Synchronizing database update/checking for bidding platform - php

I am building a platform on php/mysql that allows users to but for a percentage of a product. Basically they choose what percentage they want to bid for and the markup price they'd like to bid at e.g. 1.2.
The issue I have is that if there are several bids placed simultaneously for the same product, I need to queue the bids so when processed only the valid ones go through. For example, if there is 20% available at a value of 1.2 and two users simultaneously bid for 20% at 1.2, the process for each bid would be:
1----- select current bids
2----- php processing to work out if bid is still available
3----- place bid
The issue here is if both of the 'check if availables' happen before either of the 'place bids' then both bids will go through and effectively cause a stock issue.
Is there a way of queuing this process so the whole of steps 1-3 happen for a bid before the next one can run.
My initial thought was to use a cache table to store all the bids and then run a cron every few seconds which will process in order of ID from the cache table and notify accordingly but this seems like it may not be viable on a high traffic system as the server would get hammered over it.
Any help much appreciated

If two bids can never be identical I would solve it at the data layer. Create a unique key on your bid table based on item_id, bid_value and whatever else needs to be unique. The second insert will fail and you can let user know they were beaten to the post

I solved this at PHP level by injecting the bid as an 'accepted bid' first so that any subsequent bids would fail. Then I ran the check to see if the bid was ok, if not the bid gets removed, if it is the table gets updated as required in place for new bids.

Related

Database logic for online shop orders magament

I am designing as a project a web store (using PHP Laravel and MySQL FYI) and I am at the part where I have to create the logic behind the production system, which goes like this:
-On my Database,
I have 1 ORDER table where I have all the information regarding the shipping, customer, etc.
I have another table called ITEM where are listed all the Items in an order (so if an order has 3 items, there will be 3 lines in the ITEM table with a Foreign Key pointing to the ORDER).
Now I'm creating the PRODUCTION DASHBOARD. Right now I'm able to scan the item ID and get the shipment information on the Dashboard.
After that, for orders with multiple items what I want to do is for the system to tell the user to deposit the item in a numbered box to wait for the rest of the items from the order. That way the user can keep scanning items from other orders and once another item from the ordered stored in X box is produced, he can scan it and the system will then tell him that the other items from the same Order and placed on X box and he can do that until the order is complete.
My question is what would be the best way and logic Database wise (and also Laravel wise if you want to further expand your answer hehe) to implement this BOX system.
I hope my question is clear enough and thank you very much :)
I had a similar system for a project that I was working on. What I did was, was create a database table called temp_orders with a column called items that each item was separated by a line break. Until the order was finalized (100% processed), the order would remain in temp_orders.
Once finalized, it would get deleted from temp_orders and moved over to the orders table. If I needed to check items, I would explode() the data from the items column in temp_orders table using a line break, thus putting them into an array and then using the data however I needed to.
You need to determine when you want to finalize the order. It could be upon credit card payment, or upon user order confirmation, for example.

Is this good implementation of action-based user levelling system?

For now, the system should have 6 different user levels.
Each level will be gained upon user activity, for example:
Level 1 - When user register
Level 2 - When user completes a mission
Level 3 - When user completes more than one mission
Level 4 - When user donate > $X amount of money
Level 5 - When user write more than 50 comments in blog
Level 6 - When user complete quiz
And now... I'm wondering, what's the best database schema to achieve this? I should keep track of all actions related to user's activities, that's why I though about xp_events table... Something like this:
id # primary key
event # type of event, e.g. 'register', 'complete_quiz', etc.
user_id # id of user
delta # number of "exp" which will be gained after specific action
And... in users table I will keep record of current level and "exp" which each user has earned until now.
When user makes any activity, I will call a trigger which will check if user have new level unlocked.
But... I'm aware that in long term (e.g. if more levels are added), this isn't optimal solution.
Looking forward for any suggestions.
I see two obvious possibilities here.
One is to have an event table like you say, with a user ID, event ID, dollar amount (for donations), probably a date/time, maybe other data. If the only reason why you are keeping any of this data is to determine each user's level, this is simple and effective.
If you're keeping track of this data for other purposes also, you probably want to separate it into multiple tables. In such a case you would likely have other data you need to keep for each event. Like for a donation you would need dollar amounts, which I assume don't apply to comments and missions. For comments you likely need the text of the comment and some indication of the thread this comment is on or what it's subject is. For a mission -- I don't know what a "mission" is in this context, but you likely want some information about the type of mission and where it was or who they were supposed to kill or whatever. Most of this data would not be applicable to events of different types. A comment probably doesn't have a dollar amount, a mission doesn't have a thread, etc. So you'd end up with a lot of irrelevant data and bunches of null fields.

Trading Engine Fill or Kill

I am currently trying to implement a trading engine. My code can successfully create and fill limit and market orders. In addition, I would like my engine to have the ability to successfully fill "Fill or Kill" orders. Unfortunately, I have no idea how to write an algorithm for this "Fill or Kill". Does anyone know if there is an efficient algorithm for doing this?
The following is some background for those of you with less trading knowledge. Usually assets to be bought are ordered in a manner such as the following:
Price Amount
$200 3
$300 4
$350 2.5
$400 1.11
If one wants to buy assets, a simple algorithm goes from top to bottom in order to give the customer the best value. A whole row does not have to be completely bought. For example, if I want 4 apples, the code will sell me 3 for $200 and 1 for $300 (going from top to bottom).
Now, certain sellers may give the option of "Fill or Kill". This means that a given row cannot be bought partially. So now lets say that the second row is designated "Fill or Kill":
Price Amount
$200 3
$300 4 (Fill or Kill)
$350 2.5
$400 1.11
In this case, if I want 4 apples, I cannot buy less than 4 from the second row. So now I have two obvious options. I can buy 4 apples from the second row for 4*$300=$1200, or I can buy three apples from the first row, and 1 from the third for a price of (3*$200)+(1*350)= $850. Now in this case, the second option is the better deal. Unfortunately, that will not always be the case depending on the different prices and amount of orders.
These tables will be implemented in SQL and ordered by price. I am trying to implement this algorithm in php. Any help will be greatly appreciated.
The purpose of a "Fill or kill" order is, to ensure that a position is placed to the market at a desired price. Therefore the transaction should be immediately and completely or not enter the market at all. A FOK order prohibits a broker from partially filling. You need a 1:1 order to market match, before the order is placed in the queue/book.
The "no partial fulfillment" is what differentiates "Fill Or Kill" (and "All or None") orders from "Immediate Or Cancel" orders. IoC orders allow partial filling and wait in the book to get more stock incrementally until order expiration time.
The difference between FOK orders and AON orders is, that AON, which cannot be executed immediately remain active until they are executed or cancelled. AON keeps waiting in the book for full match.
FOK gets dropped, if no immediate full match.
Efficient algorithm for Fill Or Kill?
There are two forms "Multi Fill Or Kill" and "Single Fill or Kill".
Single Fill Or Kill
This is probably the easier one. It's a 1:1 match of order to market. If no direct order match, kill. If you do this with a SQL command you have WHERE equals comparisons.
Single means: the order will be rejected, if it cannot be immediately filled against a single order of equal or greater size.
Multi Fill Or Kill
This is probably the algorithm, which you are after.
Multi means: fill with multiple internal orders.
It's said that a FOK order prohibits a broker from partially filling.
That's only true, for the order book communication to the outside.
Internally, an "immediate interal partial filling" happens, until the order is "filled".
For the incoming FOK order, you create an OrderEventGroup.
The matcher might have multiple orders sitting on the book that allow to satisfy the incoming FOK order, but only IF ADDED TOGETHER. On the MatchEvent the OrderEventGroup, is filled with contra-orders matching the order constraint. You match orders in order book, where the quantity/price is lower or equal to the requested amount and price. You fill the OrderEventGroup until the FOK.order.amount equals OrderEventGroup.amountTogether. If OrderEventGroup.amountTogether doesn't sum up at all and/or takes longer than, what you defined as "immediate" execution time, the FOK order is killed.
You get a single transaction, which might have multiple matching steps, with possibly different prices. But that's not communicated. The order report contains: "filled" and "price", "qty" - where price is the average price of the OrderEventGroup. The order submitter would not even know that his order was filled against more than one other order.
The good thing: elimination of execution risk for the order submitter.
The bad thing: you get the average price, without a clue of min max prices in the OrderEventGroup or the number of collected contra-orders.
Fill And Kill
Then, there is "Fill and Kill".
The order is filled to the extent of the quantity that can be immediately filled at the requested price. The remainder of the order is killed/canceled. These orders might end with a status "partially filled". The algo is the same as under 2., except that FOK.order.amount doesn't have to equal OrderEventGroup.amountTogether. The OrderEventGroup.amountTogether is allowed to be lower (partial fill).
The matching algorithm used is mainly a pure time priority (FIFO) algorithm, because this kind of algorithm maximizes the number of effective orders. (Some markets use Pro-Rata matching. And somewhere in-between are LIFFE and the CME algorithms, both combining elements from fifo and pro-rata.)
There should be a pseudo-polynomial dynamic programming solution, similar to that for the knapsack. Maintain a table giving, for all quantities <= the desired quantity, the lowest possible cost at which that quantity can be bought. Start with all entries in the table set to the best you can get using only ordinary offers. Take each fill or kill offer in turn and use this to ammend the table: the new cheapest price to quantity k is min(previous price for k, previous price for k-x plus cost to provide x shares according to the offer you are currently considering). Keep enough backtrack information to work back to a combination of offers from the cheapest price for the target quantity after considering all fill or kill offers. This could be, for instance, a note, for each offer, of the quantities for which it forms part of the cheapest price.
You can skip the offer with the attribute "Fill or kill" and pick the next product. Then repeat with the skipped offer and find the cheapest combination between both solutions.
First, FOK don't sit on the order book. They are like IOC (Immediate Or Cancel) and have a Time In Force of zero. If they don't execute, they are cancelled immediately.
All Or None orders, which are even less supported and less standard, might be have a TIF of end of day or good till cancel. In that case they are not displayed and will execute when they are able to.
Now with that our if the way, are you trying to obey securities law, or is this just a toy system? FOK aren't as standardized a Limit, Market, or IOC orders. Some venues may not even implement them and some have have different definitions if they do.
But, if you are trying to obey RegNMS, you cannot skip the inside of the book to fill deeper (the trade through requirement). I only ever see FOK orders filled on the the NBBO (best bid/offer, the inside), but I think I've used them at once place only that I can remember.
So the algorithm would be simple to see if the inside of the book has enough size and if so, execute against it. If you wanted to be a little more lenient, you could work to the next level, however under RegNMS, a venue couldn't do that if another venue was also showing size at that level (trade through strikes again). That is kind of the point of the order type though, to prevent leakage of your intent to buy/sell.

How to prevent race condition in online hotel booking

I am writing a hotel booking software using PHP and MySQL. I am pretty much done with it but I ran into a race condition problem. For example there is only one standard room left and when 2 guests both select it it shows available to both of them. I tried fixing it by checking the room again when the guest clicks confirm before payment but that still has issues. I also tried making the room status to pending when whoever clicks the confirm first but I can't figure out how to change it back to available if the guest decides not to pay or just closes the browser. I searched SO for answers but I didn't really find a definitive answer. Thanks in advance
One solution is to add two columns to a table in the database. One column is the session ID or user ID or whatever of the user that is being offered the room. The second column is a timestamp indicating when that offer will expire.
Then, in your app, only show rooms that have an expired timestamp in the hold column. (Set the initial timestamp to 0 so that it starts out expired.) When a room is selected, check the column again. If there's an unexpired timestamp there, the user gets a "sorry, you were too slow" message. Otherwise, put a timestamp there for 15 minutes into the future or whatever, and proceed.
You see this on travel sites and ticket-purchasing sites a lot where it says something like "We're holding these seats for you for another 14 minutes. Please complete the transaction by then or it will be released blah blah blah."
I would also go with the pending state. You could save the state together with the session id of this user and have a cronjob that deletes all pending states that have expired session ids associated to them.

MySQL/PHP: Selecting jobs with outstanding balances

Hopefully I can do this without writing a book... I'm working on a system for a Surveying company. They're also throwing in an accounting section, and one of the functionalities it needs is to find jobs that are not completely paid off.
A few points to be made:
A 'job' is a project, essentially. There are different types of surveys.
A job can have more than one "type" of survey in it, thus having more than one price that is calculated into the job's total price.
Payments are made on individual jobs (the client might send 30 checks if they have 30 jobs, it's an accounting thing)
Job types are dynamic (they can create/delete them from the system panel) - so I can't hardcode these things
Here's the applicable database structure:
table jobs: job_id, client_id
table job_types: type_id, type_name
table job_type_assoc: id_job, type_id, price
table payments: payment_id, job_id, amount
Note: payments aren't made on each job type, but the JOB as a whole (again, as opposed to the client's account having a "balance").
I need to somehow pull jobs where the total of price from job_type_assoc is less than the total of amount in payments.
I don't know if this is possible in mysql alone or if php would be more efficient - also, their old system has about 340,000 jobs in it. Granted that they won't have the accounting info from then, they do have a lot of work and the new entries will build quickly, AND if I somehow do it in PHP where I end up querying the jobs table a lot, it might get messy.
One possible way you can do this is with a clever combination of subqueries.
select * from
(select job_id,
(select ifnull(sum(job_type_assoc.price),0) from job_type_assoc
where jobs.job_id = job_type_assoc.id_job) as amount_due,
(select ifnull(sum(payments.amount),0) from payments
where jobs.job_id = payments.job_id) as payments
from jobs) as outstanding
where payments< amount_due;
This shouldn't be too bad a query to run, if you have properly indexed job_type_assoc and payments.
Please note that I haven't tested this exact query, so it might need tweaking. I've run the same query against tables on my local DB.

Categories