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.
Related
I needed to advise about the woocommerce plug-in invoice, do you know any way of doing this if we have more languages on the site, such as EN, PL, CZ, HUN, so for each language we need separate invoice numbering. That means if the EN buyer purchases the product, then the invoice number starts 20190001 and if another client comes from the PL and purchases the product so that his invoice is again 20190001 because it is from another country? And so for all countries, each has a separate number of invoices.
Thanks for helping
A large part of the value of having an invoice number is that it uniquely identifies a transaction. If you implement your strategy, you will always need two pieces of information to identify the invoice, specifically the invoice number and the language code. If the language code is a business requirement, I would suggest you use a smart number format. A smart number is a unique identifier that communicates additional information about the entity identified. For example, in your case, the first invoice could be EN001, the second invoice PL002. The first two characters are a language code. The second three characters are a sequential number, and you know by looking at the second three characters that this was the n-th invoice created.
A disadvantage of using sequential numbers is that you expose some information about the volume of your business. This is sometimes illustrated as the "German Tank Problem", based on the story of how the Allies in World War 2 used the serial numbers found on captured / destroyed German tanks to estimate manufacturing capabilities, and subsequently the number of tanks the Germans had. More info: https://en.wikipedia.org/wiki/German_tank_problem
You could use a series of number for each language code, such as EN001 and PL001, but you would decrease the amount of information coded in the invoice number, and you would have a harder implementation in WooCommerce since you would need to maintain index numbers for all languages in order to create the unique invoice number for each invoice.
when i submit an edited order in which the reward points awarded is negative (because the new processed order is less than the original), in the reward history one of the entries is pushed forward 12 hours ahead of the most recent entry
this isn't causing any bad effects to the total reward points as the value is being calculated correctly
there's really nothing my edit order module could be doing that does this, to edit the order the module just does the exact same thing as what Reorder does but it also creates a new session which stores the previous order's item's, their qty, the date the order was made and it's increment id, how the points are calculated is that when they are normally calculated, there's a check for this session, if it's exists it gets the Base Grand Total, puts that though $this->getReward()->getRateToPoints()->calculateToPoints() and subtracts that from the points delta
when we process the order in the checkout, it just creates a new order but the transaction id is the same as the previous order, since internet sales looks at this transaction id they'll know which order to edit, the old order will be canceled during the next run of the synchronization scripts
given all of that, at no time do i ever do anything with the reward history and it's not always the order your editing who's reward history entry i pushed up, i went and edited order 100000040 but 100000042 was pushed up
NOTE: i should also point out that the orders are not storing the same transaction id at this time as i am waiting on sample xml to compare to the request/response xml from the payment gateway, so there is no way that an order once process is tied to another order in any way
The following code is taken from Enterprise_Reward_Model_Action_OrderExtra::getPoints, it is places between $pointsDelta = $this->getReward()->getRateToPoints()->calculateToPoints((float)$monetaryAmount); and return $pointsDelta;
$editOrder = Mage::getModel('core/session')->getData('editorder');
if(!is_null($editOrder))
{
$readConnection = Mage::getSingleton('core/resource')->getConnection('core_read');
$result = $readConnection->fetchAll("
SELECT sfo.entity_id FROM sales_flat_order AS sfo
WHERE sfo.increment_id = ?
LIMIT 1
",$editOrder['original_order']);
$order = Mage::getModel('sales/order')->load($result[0]['entity_id']);
$orderData = $order->getData();
$previousOrderMonetaryAmount = (($orderData['base_grand_total'] - $orderData['base_shipping_amount']) - $orderData['base_tax_amount']);
$pointsDelta = $pointsDelta - $this->getReward()->getRateToPoints()->calculateToPoints((float)$previousOrderMonetaryAmount);
}
above is a snapshot of what's happening, the top shows what the reward history was before en order was edited and processed, the bottom is what happens after (for #100000049 nothing happened so i had to do it again yo get the glitch showing up)
the items in #100000044 are completely different to order #100000048, order #100000046 is missing cause when the points delta is 0 (meaning no points will be added/subtracted) it doesn't show (which is good)
all the order with a negative values are processed edited orders of those which had positive values but had some items removed during the edit reducing the cart total (in the gateway, this would then refund the customer so it makes sense that they should not be allowed to have the points that they was refunded for)
The problem is to do with magento itself, by forcing a clean build of magento to always have a negative amount in the order using $pointsDelta = $pointsDelta - 100000 results in the exact same problem, no idea if Magento will consider it a bug though since the only way to have discovered it is via customization of Magento but i'll report it nun the less
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.
I've worked with a dozen or so template systems (Zen Cart, Cube Cart, etc.). Each of these has their own bizarre way of structuring products, options and categories. All the add-on features result in a McGuyver'd stack of cards situation that makes working with the code a total drag.
So six years ago I built my own webstore engine, which has evolved over the years and become its own stack of cards. Now I'm doing a total overhaul on the engine. While no one engine will suit all webstore needs, I was wondering if the following model has any drawbacks, or if there's a better way to create a flexible, normalized, non-obnoxious database for commerce:
Notes:
option_types = colors, sizes, materials
options = red, white, blue, S, M, L, cotton, spandex, leather
Other than basic stuff omitted on purpose (position, active, etc.), anyone see a way to improve this?
Here are my notes/opinions on this. You're missing cardinalities, but I'll do my best to guess them.
Categories is ok.
Remove id from item_categories as you're not using it. Create a composite primary key on category_id and item_id.
giving each record a unique id is smarter in many ways: faster to look-up on one field than on two, safer to delete, etc
What lookup would you do on that id? The queries you'll run are: "Getting all categories for an item" and "Getting all items for a category". I don't understand why it would be safer to delete. However, I'd say adding an id might be unsafer to insert as you might have different ids but same category_id and item_id pairs. You'll have to check the constraints there and make sure the pairs are unique (and aren't that what PKs are used to?)
items is ok... (see comments below)
Remove id from item_options (same case as above and see comments below)
option_types is ok
Now, I think the way items and options are related will require more thinking. It seems to be a many-to-many relationship. As an item, such as a T-Shirt can have many sizes it makes sense to say that each pair items and options should have a different size. But what happens when, apart from the size you also have a different material, such as cotton and leather. You will have to have information on the pairs cotton-S, cotton-M, cotton-L and leather-S, leather-M and leather-L. This makes sense as I'm pretty sure all of them will have a different price and weight. But now let's add 2 colors to our T-Shirts. You'll have to add a price and weight for each of the 12 combinations we'll have now.
Not to mention that if a user would like to see the price of an item he'll have to choose all the options until he reaches a price. I'm not sure how this should be done as I'm not aware of the requiremets. I'm just throwing an idea: you could apply prices and weight variations over a base price and weight that would be part of the item.
Just some unprocessed thoughts before going to sleep:
option_types could be some kind of hierarchy
Carefully think of how you would handle stock given that design. You'll have 10 items for a Black T-Shirt... but how many items will you have for a Black Leather T-Shirt? How is that number related to the 10 original ones?
Options table I would add value under name. i.e.
Black L
Black M
Black S
Blue L
Blue M
Blue S
etc.
as a spin off to Mosty's idea.
I have no idea what formulas I should use to create stock-market for my players that they could play it. I use php+mysql. Maybe you can throw any good ideas? I'll be grateful.
The simplest (but not necessarily the best) way of implementing fluctuation in stock prices is by using a random walk, since it has been hypothesised that stock prices can be modelled using such a process. See http://en.wikipedia.org/wiki/Random_walk_hypothesis
So, dp = rand(-1,1) * p * dt where p is the stock price and dt is the time elapsed (probably in days).
Assuming this is multiplayer, in addition to random walk, some consideration of supply and demand can be taken into account. If more shares are bought than sold of a particular stock over a period, its value should go up slightly, and vice-versa. This will increase volatility and perhaps make this portion of the game more exciting.
If you're allowing buying and selling between players (and assuming you've already created the storage part), you just need to expose four methods and let the players define the economy:
Bid (stock, price)
Offer (stock, price)
Buy (stock, price)
Sell (stock, price)
If the stocks already exist in your game, then you just need to let the players define what they want for theirs.