Skip to content

Commit

Permalink
Compatible with PHP 7.4
Browse files Browse the repository at this point in the history
  • Loading branch information
sting_bo committed Dec 23, 2023
1 parent fc08515 commit e2264f3
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 77 deletions.
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
"name": "sting_bo/mengine",
"description": "Matching Engine For Laravel",
"require": {
"predis/predis": "^1.1"
"php": "^7.4",
"predis/predis": "^1.1",
"ext-bcmath": "*"
},
"license": "MIT",
"authors": [
Expand Down
12 changes: 10 additions & 2 deletions config/mengine.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@

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,
],
];
3 changes: 3 additions & 0 deletions src/Core/AbstractMengine.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@ abstract public function pushHash(Order $order);
*/
abstract public function deleteOrder(Order $order);

/**
* Get Depth.
*/
abstract public function getDepth($symbol, $transaction);
}
103 changes: 55 additions & 48 deletions src/Core/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,79 +7,70 @@
class Order
{
/**
* 唯一标识,可以是用户id.
* Unique identifier, can be user ID.
*/
public $uuid;
public string $uuid;

/**
* 单据id.
* order id.
*/
public $oid;
public string $oid;

/**
* 符号.
* abc2usdt.
*/
public $symbol;
public string $symbol;

/**
* 买卖.
* Buy/Sell.
*/
public $transaction;
public string $transaction;

/**
* 数量.
*/
public $volume;
public float $volume;

/**
* 价格.
*/
public $price;
public float $price;

/**
* 精度.
*/
public $accuracy;
public int $accuracy;

/**
* 节点.
* node.
*/
public $node;
public string $node;

public $is_first = false;
public $is_last = false;
public bool $is_first = false;
public bool $is_last = false;

/**
* 节点前一个.
* prev node.
*/
public $prev_node;

/**
* 节点后一个.
* next node.
*/
public $next_node;

/**
* 节点链.
* node link.
*/
public $node_link;
public string $node_link;

/**
* hash对比池标识.
* hash Compare Pool Identifiers.
*/
public $order_hash_key;
public $order_hash_field;
public string $order_hash_key;
public string $order_hash_field;

/**
* zset委托列表.
* zset Order List.
*/
public $order_list_zset_key;
public string $order_list_zset_key;

/**
* hash委托深度.
* hash Order Depth.
*/
public $order_depth_hash_key;
public $order_depth_hash_field;
public string $order_depth_hash_key;
public string $order_depth_hash_field;

public function __construct($uuid, $oid, $symbol, $transaction, $volume, $price)
{
Expand All @@ -100,7 +91,7 @@ public function __construct($uuid, $oid, $symbol, $transaction, $volume, $price)
/**
* set uuid.
*/
public function setUuid($uuid)
public function setUuid($uuid): Order
{
if (!$uuid) {
throw new InvalidArgumentException(__METHOD__.' expects argument uuid is not empty.');
Expand All @@ -114,7 +105,7 @@ public function setUuid($uuid)
/**
* set oid.
*/
public function setOid($oid)
public function setOid($oid): Order
{
if (!$oid) {
throw new InvalidArgumentException(__METHOD__.' expects argument oid is not empty.');
Expand All @@ -128,7 +119,7 @@ public function setOid($oid)
/**
* set symbol.
*/
public function setSymbol($symbol)
public function setSymbol(string $symbol): Order
{
if (!$symbol) {
throw new InvalidArgumentException(__METHOD__.' expects argument symbol is not empty.');
Expand All @@ -142,7 +133,7 @@ public function setSymbol($symbol)
/**
* set transaction.
*/
public function setTransaction($transaction)
public function setTransaction($transaction): Order
{
if (!in_array($transaction, config('mengine.mengine.transaction'))) {
throw new InvalidArgumentException(__METHOD__.' expects argument transaction to be a valid type of [config.mengine.transaction].');
Expand All @@ -156,12 +147,21 @@ public function setTransaction($transaction)
/**
* set volume.
*/
public function setVolume($volume)
public function setVolume($volume): Order
{
if (floatval($volume) <= 0) {
throw new InvalidArgumentException(__METHOD__.' expects argument volume greater than 0.');
}
if (config('mengine.mengine.strict_mode')) { // In strict mode, the decimal places cannot exceed the configured length.
$number_string = strval($volume); // Convert the number to a string.
// Use a regular expression to match the decimal part.
if (preg_match('/\.\d{' . $this->accuracy . ',}/', $number_string)) {
throw new InvalidArgumentException(__METHOD__.' decimal places exceed the configured length.');
}
}

// Truncate the decimal part.
$volume = number_format($volume, $this->accuracy, '.', '');
$this->volume = bcmul($volume, bcpow(10, $this->accuracy));

return $this;
Expand All @@ -170,12 +170,19 @@ public function setVolume($volume)
/**
* set price.
*/
public function setPrice($price)
public function setPrice($price): Order
{
if (floatval($price) <= 0) {
throw new InvalidArgumentException(__METHOD__.' expects argument price greater than 0.');
}
if (config('mengine.mengine.strict_mode')) {
$number_string = strval($price);
if (preg_match('/\.\d{' . $this->accuracy . ',}/', $number_string)) {
throw new InvalidArgumentException(__METHOD__.' decimal places exceed the configured length.');
}
}

$price = number_format($price, $this->accuracy, '.', '');
$this->price = bcmul($price, bcpow(10, $this->accuracy));

return $this;
Expand All @@ -184,7 +191,7 @@ public function setPrice($price)
/**
* set accuracy.
*/
public function setAccuracy()
public function setAccuracy(): Order
{
$accuracy = config("mengine.mengine.{$this->symbol}_accuracy") ?? config('mengine.mengine.accuracy');
if (floor(0) !== (floatval($accuracy) - $accuracy)) {
Expand All @@ -199,7 +206,7 @@ public function setAccuracy()
/**
* 委托标识池field.
*/
public function setOrderHashKey()
public function setOrderHashKey(): Order
{
$this->order_hash_key = $this->symbol.':comparison';
$this->order_hash_field = $this->symbol.':'.$this->uuid.':'.$this->oid;
Expand All @@ -210,7 +217,7 @@ public function setOrderHashKey()
/**
* 委托列表.
*/
public function setListZsetKey()
public function setListZsetKey(): Order
{
$this->order_list_zset_key = $this->symbol.':'.$this->transaction;

Expand All @@ -220,7 +227,7 @@ public function setListZsetKey()
/**
* 深度.
*/
public function setDepthHashKey()
public function setDepthHashKey(): Order
{
$this->order_depth_hash_key = $this->symbol.':depth';
$this->order_depth_hash_field = $this->symbol.':depth:'.$this->price;
Expand All @@ -231,7 +238,7 @@ public function setDepthHashKey()
/**
* hash模拟node.
*/
public function setNode()
public function setNode(): Order
{
$this->node = $this->symbol.':node:'.$this->oid;

Expand All @@ -241,7 +248,7 @@ public function setNode()
/**
* hash模拟Link.
*/
public function setNodeLink()
public function setNodeLink(): Order
{
$this->node_link = $this->symbol.':link:'.$this->price;

Expand Down
6 changes: 2 additions & 4 deletions src/Listeners/PushQueueEventListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

class PushQueueEventListener
{
public $service;
public CommissionPoolService $service;

/**
* Create the event listener.
Expand All @@ -19,10 +19,8 @@ public function __construct(CommissionPoolService $service)

/**
* Handle the event.
*
* @param object $event
*/
public function handle(PushQueueEvent $event)
public function handle(PushQueueEvent $event): bool
{
$this->service->pushPool($event->order);

Expand Down
25 changes: 15 additions & 10 deletions src/Services/CommissionPoolService.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,17 @@ class CommissionPoolService extends AbstractCommissionPool
/**
* 放入委托池.
*/
public function pushPool(Order $order)
public function pushPool(Order $order): bool
{
$ms_service = new MengineService($order);
$ms_service = new MengineService();
if ($ms_service->isHashDeleted($order)) {
return false;
}

$ms_service->deleteHashOrder($order);
$list = $ms_service->getMutexDepth($order->symbol, $order->transaction, $order->price);
if ($list) {
// 撮合
$order = $this->matchUp($order, $list);
$order = $this->matchUp($order, $list); // 撮合
if (!$order) {
return false;
}
Expand All @@ -39,12 +38,14 @@ public function pushPool(Order $order)
$depth_link->pushDepthNode($order);

event(new PushQueueEvent($order));

return true;
}

/**
* 撤单从委托池删除.
*/
public function deletePoolOrder(Order $order)
public function deletePoolOrder(Order $order): bool
{
$link_service = new LinkService($order->node_link);
$node = $link_service->getNode($order->node);
Expand All @@ -66,17 +67,19 @@ public function deletePoolOrder(Order $order)

// 撤单成功通知
event(new DeleteOrderSuccEvent($order));

return true;
}

/**
* 撮合.
*
* @param object $order 下单
* @param array $list 价格匹配部分
* @param Order $order 下单
* @param array $list 价格匹配部分
*
* @return mix
* @return null|Order
*/
public function matchUp(Order $order, $list)
public function matchUp(Order $order, array $list): ?Order
{
// 撮合
foreach ($list as $match_info) {
Expand All @@ -93,7 +96,7 @@ public function matchUp(Order $order, $list)
return $order;
}

return false;
return null;
}

public function matchOrder($order, $link_service)
Expand Down Expand Up @@ -136,6 +139,8 @@ public function matchOrder($order, $link_service)
// 撮合成功通知
event(new MatchEvent($order, $match_order, $match_volume));
break;
default:
break;
}

return $order;
Expand Down
Loading

0 comments on commit e2264f3

Please sign in to comment.