Matching Engine For Laravel,Based on Redis,High-Performance
composer require sting_bo/mengine
php artisan vendor:publish
For existing systems with data, if using this library, you can write an initialization script to first run the data into the queue.
After placing an order, store it in the database and then instantiate the order object.
use StingBo\Mengine\Core\Order;
$uuid = 3; // User unique identifier
$oid = 4; // Order unique identifier
$symbol = 'abc2usdt'; // Trading pair
$transaction = 'buy'; // Trading direction, buy/sell
$price = 0.4; // Trading price, will be converted to an integer based on the set precision
$volume = 15; // Trading quantity, will be converted to an integer based on the set precision
$order = new Order($uuid, $oid, $symbol, $transaction, $volume, $price);
Transaction direction
andprecision
can be flexibly set in the configuration file.
return [
'mengine' => [
// Transaction types, not subject to change.
'transaction' => [
'buy',
'sell',
],
// Default precision, can be changed.
'accuracy' => 8,
// If the precision for the trading pair is set, use it; otherwise, take the default accuracy.
'abc2usdt_accuracy' => 6, // Example of a trading pair
'test2usdt_accuracy' => 7, // Example of a trading pair
// If strict mode is set to true, it will validate that the decimal places of the transaction volume or price must be less than the configured length, otherwise the order will fail.
// If strict mode is set to false, the data will be truncated to the configured decimal places length.
'strict_mode' => false,
],
];
use StingBo\Mengine\Services\MengineService;
$ms = new MengineService();
$ms->pushQueue($order);
Start the queue task:
php artisan queue:work --queue=abc2usdt
You can also use horizon
and supervisor
to assist, making your work more efficient!
When the queue is consumed, it will enter the matching program. The general steps are as follows:
// Successful match notification, parameters are: current order, matched order, transaction quantity
event(new MatchEvent($order, $match_order, $match_volume));
// Register listener
protected $listen = [
'StingBo\Mengine\Events\MatchEvent' => [
'App\Listeners\YourListener', // Your own listener, should also be implemented asynchronously
],
];
// Order pool data change event
event(new PushQueueEvent($order));
// Register listener
protected $listen = [
'StingBo\Mengine\Events\PushQueueEvent' => [
'App\Listeners\YourListener', // Your own listener, should also be implemented asynchronously
],
];
The cancellation process should be to first query the database to confirm if it can be canceled, then successfully delete the data from redis, and finally update the database.
$order = new Order($uuid, $oid, $symbol, $transaction, $volume, $price);
$ms = new MengineService();
$ms->deleteOrder($order);
This matching engine does not implement locking mechanisms like databases. To prevent a situation where an order is being matched and a cancellation command is issued, both placing and canceling orders use the same queue to ensure order, and each trading pair has an isolated queue. This ensures efficiency, but developers need to implement asynchronous notification functionality. Register the listener as follows:
// Successful cancellation notification
event(new DeleteOrderSuccEvent($order));
// Register listener
protected $listen = [
'StingBo\Mengine\Events\DeleteOrderSuccEvent' => [
'App\Listeners\YourListener', // Your own listener, should also be implemented asynchronously
],
];
$symbol = 'abc2cny';
$transaction = 'buy';
$ms = new MengineService();
$ms->getDepth($symbol, $transaction);
Tested on a local, average matching speed for transactions is around 200 per second. Further optimizations for matching speed are planned for the future.
contact us | detail |
---|---|
QQ Group | 871358160 |
[email protected] |